■ 外付けSPIインターフェース部品の読み書き
SPIは部品間の通信でよくつかわれています。以下にその使用例を紹介します
(1)12ビットA/Dコンバータ読み込み <CCS編>
(2) 2-1、12ビットD/Aコンバータへの書き込み(SPIモジュールから出力) <C30 dsPIC編> <C30 PIC24編>
2-2、12ビットD/Aコンバータへの書き込み(汎用I/Oポートから出力) <C30 dsPIC編>
(3)SDカード読み書き
★ 読み書き(ファイルオープン、リード、ライト) <C30 dsPIC 編> <PIC32MX編>
★ 読み書き(FIFO) <C30 dsPIC編> <PIC32MX編>
★ 読み書き(EOF) <C30 dsPIC編> <PIC32MX編>
★ ADコンバータ値の読み書き <C30 dsPIC編>
★ 音声の録音と再生 <C30 dsPIC編>
★ WAV録音付きMP3プレーヤー
(1)12 ビット A/D コンバータ読込み
12ビットADコンバータとしては マイクロチップテクノロジー社のADコンバータ MCP3204を使いました。
MCP3204はマイクロチップテクノロジー社から直接通販(約3ドル/個)で購入することができます。また、8チャンネル
タイプのMCP3208が秋月電商の通販(400円/個)で購入できます。
<MCP3204の主要諸元>
・ 種類 …… 逐次比較型ADコンバータ(Succesive Approximation Anaogue-Digital Converter)
・ 分解能 …… 12ビット
・ 変換速度(サンプリングレート) …… 100Ksps ( at 電源電圧=5V) (注)
・ チャンネル数 …… 4チャンネル
・ 電源電圧範囲 …… 2.7V〜5.5V
・ パッケージ …… PDIP SOIC TSSOP
(注) sps (sampling per second):A/D変換してとりだせるサンプリングデータ(MCP3204の場合12ビットデータ)の
1秒間あたりの数
<試作品仕様>
・ 電圧範囲 -5V 〜 +5Vの電圧を12ビットADコンバータで読込みこむ
・ PICに接続された液晶の上段には読込んでいる整数の値を 下段には測定電圧を V(ボルト)で表示する
・ ADコンバータの読込み及び液晶表示は200msec毎にタイマ割込みをつかっておこなう
<MCP3204の使い方> (詳細はマイクロチップテクノロジ社のデータシートを参照してください)
MCP3204は標準のSPIインターフェースのADコンバータです。A/D変換された値を読取る手順は以下のようになります。
@ PIC側よりMCP3204のCS端子をhigh→lowにする。
A PIC側よりMCP3204のCLK端子をhigh→lowにする。これがスタートビットとなる。
尚、この時のDin端子はhighのままにしておく。
B MCP3204のCLK端子への信号をlow→highにする。このタイミングでMCP3204はスタートビットを認識します。
C AD変換アンプをシングルエンドアンプで使うか差動アンプで使うかか下表にしたがってMCP3204のDin端子へ
low/high信号を出力します。CLK端子をlow→highにします。MCP3240はDin端子情報を読込みます。
★MCP3204はCLKがlow→highのタイミングでDinの情報を読込みます。
D つづく3ビットでどのチャンネルをつかうかをMCP3204のDin端子に読込ませます。
E 3ビット目を読込ますクロックがlow→highになったあと1.5サイクルの間にデータがホールドされサンプリングが
おこなわれます。
F このあとのクロックlow→highのあとDout端子出力は無効なデータです。
G 次のクロックのlow→highのあとMCP3204のDout端子にはA/D変換された12ビットデータのMSB(B11)が
出力されてきます。これをPIC側で読み込みます。
H このあとクロックをlow→highとしてB10を読込みます。 以下これをくりかえします。
I LSB(B0)まで読み込んだら CSをlow→highにします。
★ MCP3204のCLK端子への入力クロックは最大2MHz(Clock Low Time(最小)=500nsec Clock High Time
(最小)=500nsec) ですので プログラム設計の際、クロックのLow Time /High Timeが不足した場合は
ウエイトをおこなう必要があります。
<試作品回路図> (→回路図のPDFファイル)
PIC18F4550をつかった場合の回路図を以下に示します。測定電圧範囲が-5v〜+5Vなので-5Vレベルシフトして
からOPアンプで極性を反転させ、またアンプゲイン1/2にしてからMCP3204で読込むようにしています。
MSSPは使用しないで一般のI/Oポートのモードで直接読書きしています。
<試作品外観> 下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています。
以下のプログラム例の中にある液晶表示器制御ライブラリ 1llcd_lib.cは 後閑哲也さんが設計されたものです
<プログラム例> #include <18F4550.h> #use delay(clock=20000000) #FUSES HS,PUT,NOWDT,BROWNOUT,BORV43,NOPROTECT,NOLVP //////// Port define and link LCD library #define mode 0 #define input_x input_D #define output_x output_D #define set_tris_x set_tris_D #define rs PIN_D2 //chip select #define stb PIN_D0 //strobe #include <1lcd_lib.c> unsigned long int myAD(){ int i; unsigned int config; unsigned long int AdValue = 0; //AD開始 output_high(PIN_C7);// Din(start bit): high(start) output_low(PIN_C6);//CS:low output_low(PIN_B1);//CLK: low delay_cycles(3);// 600nsec ( = 50nsec × 4 × 3 サイクル)ウェイト output_high(PIN_B1);//CLK: high MCP3204がスタートビットを読み込み delay_cycles(3);// 600nsec ( = 50nsec × 4 × 3 サイクル)ウェイト // ADコンバータの条件設定(シングルエンドか差動か、どのチャンネルを読むのか) config = 0b00001000; // bit3:single/diff bit -> single = 1 シングルエンド選択 // bit2:nosignificant -> 1 // bit1,bit0 chanel No set 00 -> ch0 チャンネル0を選択 i = 0; for(i = 0; i < 4; i++){ output_bit(PIN_C7,bit_test(config,3-i)); output_low(PIN_B1);//CLK: low delay_cycles(3); output_high(PIN_B1);//CLK: high MCP3204がconfig bitを読み込み delay_cycles(3); } // 2クロックウェイト --> MCP3204 ADコンバータの値をホールド&サンプリング i = 0; for(i = 0; i<2; i++){ output_low(PIN_B1);//CLK: low delay_cycles(4); output_high(PIN_B1);//CLK: high delay_cycles(4); } // MP3204が出力する12ビットデータを順次読込む i = 0; for(i = 0; i < 12; i++){ output_low(PIN_B1); //CLK: low delay_cycles(3); output_high(PIN_B1);//CLK: high MP3204がデータをDoutに出力 delay_cycles(3); if(input(PIN_B0) == 1) bit_set(AdValue,11-i); //Doutが 1か0か判別 else bit_clear(AdValue,11-i); } delay_cycles(3); output_high(PIN_C6);//CS:high return AdValue; } #int_timer0 //タイマ0割込み interval(){ unsigned long int adValue; float volt; set_timer0(61630); // 256*256 -3906 = 61630 // 0.05 usec * 4 * 256 * 3906 = 200000 usec =200 msec adValue = myAD();// ADコンバータが読込んだ値(12ビット整数) MCP3204 if(adValue >= 4095) adValue = 4095; if(adValue <= 0) adValue = 0; volt = -((float)adValue - 2048)/2048 * 5 ; //ADコンバータが読込んだ値を電圧値に換算 // 液晶表示 lcd_clear(); printf(lcd_data,"adValue=%4lu",adValue); // ADコンバータMCP3204が読込んだ値の表示 lcd_cmd(0xC0); // 2行目の先頭へ printf(lcd_data,"V = %5.3f[V]",volt); //電圧換算値を表示 return 0; } main(){ setup_timer_0(RTCC_INTERNAL |RTCC_DIV_256); set_timer0(61630); lcd_init(); lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); printf(lcd_data,"start!!"); enable_interrupts(INT_TIMER0); enable_interrupts(GLOBAL); while(1) // 割込みを待つ { output_high(PIN_C6); // CS:high } return 0; } //--------------------------------------------------------------------------- //************************************** //インクルードファイル 1lcd_lib.c //このファイルは後閑哲也さんが設計されたものです //************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 //////// データ出力サブ関数 void lcd_out(int code, int flag) { output_x((code & 0xF0) | (input_x() & 0x0F)); if (flag == 0) output_high(rs); //表示データの場合 else output_low(rs); //コマンドデータの場合 delay_cycles(4); //NOP 1 output_high(stb); //strobe out delay_cycles(8); //NOP 2 output_low(stb); //reset strobe } //////// 1文字表示関数 void lcd_data(int asci) { lcd_out(asci, 0); //上位4ビット出力 lcd_out(asci<<4, 0); //下位4ビット出力 delay_us(50); //50μsec待ち } /////// コマンド出力関数 void lcd_cmd(int cmd) { lcd_out(cmd, 1); //上位4ビット出力 lcd_out(cmd<<4, 1); //下位4ビット出力 delay_ms(2); //2msec待ち } /////// 全消去関数 void lcd_clear() { lcd_cmd(0x01); //初期化コマンド出力 delay_ms(15); //15msec待ち } /////// 初期化関数 void lcd_init() { set_tris_x(mode); //モードセット delay_ms(15); lcd_out(0x30, 1); //8bit mode set delay_ms(5); lcd_out(0x30, 1); //8bit mode set delay_ms(1); lcd_out(0x30, 1); //8bit mode set delay_ms(1); lcd_out(0x20, 1); //4bit mode set delay_ms(1); lcd_cmd(0x2E); //DL=0 4bit mode lcd_cmd(0x08); //display off C=D=B=0 lcd_cmd(0x0D); //display on C=D=1 B=0 lcd_cmd(0x06); //entry I/D=1 S=0 lcd_cmd(0x02); //cursor home }
<動作結果>
測定電圧に-2.36Vが入力された時の液晶表示を下記に示します。
(2) 12ビットD/Aコンバータへの書き込み <dsPIC C30編>
(2−1) SPI モジュールを使用した場合
マイクロチップテクノロジーのD/AコンバータMCP4822をSPI通信で制御したD/A変換の例を紹介します。
<試作品の仕様>
・ PICで1度毎の正弦波テーブルを生成し、このデータを200KHzでサンプリングしてSPI通信でD/Aコンバータ
MCP4822に伝送する。
・ MCP4822(電源電圧+5V)からは、555Hz(注)、Vp-p 4.096V、分解能12ビットの正弦波電圧を出力する。
(注)555Hz = 200KHz ÷ 360
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //******************************************************************************************************** // 外付けDAコンバータMCP4822 // SPI通信による正弦波出力 // サンプリング周波数:200KHz 出力正弦波 12bit 555Hz dsPIC30F4013 //******************************************************************************************************** // MPLABのLink File // Linler Script : p30f4013.gld // Library File : libp30F4013-coff.a #include <p30f4013.h> #include <timer.h> #include "math.h" #include "spi.h" #define Clock 80000000 // 単位はHzで指定 _FOSC(CSW_FSCM_OFF & // クロック切り替えなし、フェールセイフクロックモニタなし XT_PLL8 //外部発振子周波数 × ポストスケーラ:1 × PLL:8倍 → 10MHz × 1 × 8 = 80MHz ); _FWDT(WDT_OFF); //ウォッチドックタイマ:OFF _FBORPOR(PBOR_ON & //ブラウンアウトリセット機能:ON BORV_42 & //ブラウンアウト電圧:4.2V PWRT_64 & //パワーオンリセットタイマ64msec MCLR_EN //MCLR機能:ON ); _FGS(CODE_PROT_OFF); //コードプロテクト:OFF unsigned int Fre_Out = 1000; // 出力周波数 1KHz unsigned int Fre_Sampling = 200000; //サンプリング周波数200KHz unsigned int sinValue[360]; //sinテーブル値 RAM容量が少ないので大きな値(例1000)をとると不可解な現象がでる unsigned int angleValue = 0; // float PAI = 3.1416; int Led = 0; //// SPIの初期設定パラメータ クロック20MHz unsigned int SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_INPUT & ENABLE_SDO_PIN & SPI_MODE16_ON & SPI_SMP_ON & SPI_CKE_OFF & CLK_POL_ACTIVE_LOW & MASTER_ENABLE_ON & SEC_PRESCAL_1_1 & PRI_PRESCAL_1_1; unsigned int SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR; void _ISR _T1Interrupt(void) //5μsec毎の割込み発生 { LATDbits.LATD8 = 0; //CS = 0; IFS0bits.T1IF = 0; //IFS0レジスタの T1IF(タイマ1の割込み検出)フラグリセット WriteSPI1(sinValue[angleValue] | 0b0001000000000000); //VoutAにゲイン2で出力 //MCP4822への書き込みコマンド //bit15(書き込みレジスタ選択) 1:VoutB 0:VoutA //bit14(予備) //bit13(出力ゲイン選択) 1:1倍 0:2倍 //bit12(出力オフ制御) 1:出力ON 0:出力OFF //bit11〜bit0 データ MSBから順次送信される angleValue++; if(angleValue >= 360)angleValue = 0; //1μsec delay ( Nop()0.05μsec ×20個 = 1μsec ) // 0.2μsec以下NG Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); LATDbits.LATD8 = 1; //CS = 1 → CSの立ち上がりエッジでMCP4822の出力レジスタに送信データがラッチされる } void SinTable() //Sin のテーブル作成 { unsigned int i; for(i = 0; i < 360; i++) { sinValue[i] = (unsigned int)(4095*(1 + sinf(2*PAI*i/360))/2); //sinf():単精度 vs sin():倍精度 } } int main(void) { TRISD = 0; //ポートDを出力モードに設定 TRISF = 0; //タイマ1設定 OpenTimer1(T1_ON & //タイマ1ON T1_GATE_OFF & //ゲート制御off T1_PS_1_1 & //プリスケーラ 1/1 T1_SYNC_EXT_OFF & //クロック同期制御OFF T1_SOURCE_INT , //クロック源:内部クロック (unsigned int)(80000000/4/ 200000/1 - 1) // サンプリング周波数200KHz ); //SPI通信設定 OpenSPI1( // SPI1CONレジスタとSPI1STATレジスタの設定 FRAME_ENABLE_OFF & //フレーム制御なし<Frame SPI support Enable/Disable:FRMEN> FRAME_SYNC_INPUT & //フレーム制御時の入出力方向<Frame Sync Pulse direction control:SPIFSD> ENABLE_SDO_PIN & //SDOピンを汎用ピンとしてではなくSPI制御用として使用 <SDO Pin Control bit:DISSDO> SPI_MODE16_ON & //送受信単位:16ビット (8ビット→ SPI_MODE16_OFF)<Word/Byte Communication mode:MODE16> SPI_SMP_ON & //データ入力サンプルフェーズ:データ出力時間の終了時に入力データをサンプルする<SPI Data Input Sample phase:SMP> SPI_CKE_OFF & //クロックエッジ選択:IDLE 状態からアクテイブクロック状態に遷移するエッジでシリアル出力データが変化CKE=0<SPI Clock Edge Select:CKE> // SLAVE_SELECT_ENABLE_OFF &//SS ピン有効化:SSピン使用せず<SPI Slave Select enable:SSEN> CLK_POL_ACTIVE_LOW &//クロック極性選択ビット:アクティブ状態Low(CKP=1)<SPI Clock polarity select:CKP> //SDカードはクロックの立ち上がりでデータを取り込む → CKE=0 CKP=1 MASTER_ENABLE_ON & //マスターモード有効化:マスターモードに設定<SPI Mode Select bit:MSTEN> SEC_PRESCAL_1_1 & //2次プリスケール選択: 1:1<Secondary Prescale select:SPRE2-SPRE0> PRI_PRESCAL_1_1, //1次プリスケール選択: 1:1<Primary Prescale select : PRE1-PRE0> //SPIクロック周波数=Fosc × 1/4 ÷ (1次プリスケーラ×2次プリスケーラ) // = 80MHz × 1/4 ÷ ( 1 × 1) = 20MHz SPI_ENABLE & //SPI有効無効設定: 有効<SPI Enable/Disable:SPIEN> SPI_IDLE_CON & //アイドル時の動作設定: 動作<SPI Idle mode Operation:SPISIDL> SPI_RX_OVFLOW_CLR); //オーバーフロー発生時フラグクリア:クリア<Clear Receive Overflow Flag bit:SPIROV> SinTable(); //Sinのテーブル作成 ConfigIntTimer1( T1_INT_ON & T1_INT_PRIOR_5 ); //タイマ1割込みON 割込みレベル5 ConfigIntSPI1(SPI_INT_DIS & SPI_INT_PRI_6); //SPI割込みOFF EnableIntT1; //割込み許可 while(1) { } CloseTimer1(); CloseSPI1(); return 0; }
<動作結果>
D/Aコンバータ MCP4822のVoutA(8番ピン)端子の出力電圧の波形を以下に示します。
出力電圧諸元
・周波数 : 555Hz
・分解能 : 12ビット
・振幅(Vp-p) : 4.096V
・サンプリング周波数 : 200KHz
(測定器:デジタルオシロ 岩通 DS-5102)
(2A) 12ビットD/Aコンバータへの書き込み <PIC24 C30編>
SPI モジュールとして、 マイクロチップテクノロジーのD/AコンバータMCP4822をSPI通信で制御したD/A変換の例を紹介します。
<試作品の仕様>
・ PICで1度毎の正弦波テーブルを生成し、このデータを100KHzでサンプリングしてSPI通信でD/Aコンバータ
MCP4822に伝送する。
・ MCP4822(電源電圧+3.3V)からは、277.5Hz(注)、Vp-p 2.7V、分解能12ビットの正弦波電圧を出力する。
(注)277.5Hz = 100KHz ÷ 360
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> ///************************************************************/ // SPI通信による正弦波出力 // サンプリング周波数:100KHz 出力正弦波 12bit 277.5Hz PC24FJ64GA002 //************************************************************/ #include "p24FJ64GA002.h" #include <timer.h> #include "math.h" #include "spi.h" #define Clock 32000000 // 単位はHzで指定 /// コンフィギュレーション ビットの設定 _CONFIG1( JTAGEN_OFF & //JTAGポート: OFF GCP_OFF & //コードプロテクト: OFF GWRP_OFF & //書き込みプロテクト: OFF BKBUG_OFF & //バックグランドデバック: OFF COE_OFF & //クリップオン エミュレーション: OFF ICS_PGx1& //ICDピンの選択: EMUC/EMUDをPGC1/PGD1と共用 FWDTEN_OFF )//ウォッチドックタイマ: OFF _CONFIG2( IESO_OFF & // 2速度スタートアップ機能:OFF FNOSC_FRCPLL & //内臓高速RC発振(8MHZ)回路 + 4倍PLL → 32MHz(= 8MHz × 4) FCKSM_CSDCMD & //クロック切替え制御:OFF クロックモニタ:OFF OSCIOFNC_OFF & //OSCO/RC15 function: OSCO or Fosc/2 IOL1WAY_OFF & //RP Register Protection: Unlimited Writes To RP Registers I2C1SEL_PRI & //I2C1 pins Select: Use Primary I2C1 pins POSCMOD_NONE) //発振回路モード Oscillator Selection: Primary disabled unsigned int sinValue[360]; //sinテーブル値 RAM容量が少ないので大きな値(例1000)をとると不可解な現象がでる unsigned int angleValue = 0; // float PAI = 3.1416; void _ISR _T1Interrupt(void) //10μsec毎の割込み発生 { LATBbits.LATB7 = 0; //CS = 0; チップセレクト IFS0bits.T1IF = 0; //IFS0レジスタの T1IF(タイマ1の割込み検出)フラグリセット WriteSPI1(sinValue[angleValue] | 0b0001000000000000); //VoutAにゲイン2で出力 //MCP4822への書き込みコマンド //bit15(書き込みレジスタ選択) 1:VoutB 0:VoutA //bit14(予備) //bit13(出力ゲイン選択) 1:1倍 0:2倍 //bit12(出力オフ制御) 1:出力ON 0:出力OFF //bit11〜bit0 データ MSBから順次送信される angleValue++; if(angleValue >= 360)angleValue = 0; //1μsec delay ( Nop()0.05μsec ×20個 = 1μsec ) // 0.2μsec以下NG Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); LATBbits.LATB7 = 1; //CS = 1 → CSの立ち上がりエッジでMCP4822の出力レジスタに送信データがラッチされる } void SinTable() //Sin のテーブル作成 { unsigned int i; for(i = 0; i < 360; i++) { sinValue[i] = (unsigned int)((1 + sinf(2*PAI*i/360))/2*4095*3.3/5); //sinf():単精度 vs sin():倍精度 //Vout = 2.048×2×Dn/4095 Vout(max) = 4.096[V] ( > 3.3V(電源電圧)) 4.096×3.3/5 = 2.7V (< (3.3V時オペアンプ飽和電圧)) } } /// メイン関数 int main(void) { TRISB = 0; //Bポートを出力モードに設定 CLKDIV = 0; //内蔵FRC8MHz: 分周なし直結 ★このレジスタを明示的にリセットしておかないとFRCが分周されてくることがある(?) RPOR2bits.RP5R = 8; //RB5(RPOR2レジスタのRP5)に機能8(SCK1OUT)を割り付ける RPOR3bits.RP6R = 7; //RB6(RPOR3レジスタのRP6)に機能7(SDO1)を割り付ける // タイマ1: 周期 10 μsec サンプリング周波数:100KHz OpenTimer1 ( T1_ON & //タイマ1ON T1_GATE_OFF & //ゲート制御off T1_PS_1_1 & //プリスケーラ 1/1 T1_SYNC_EXT_OFF & //クロック同期制御OFF T1_SOURCE_INT, //クロック源:内部クロック 159 //10*(32MHz/2MHz)=160 PR1設定値 = 159 (=160-1) ); //SPI通信設定 spi.h参照(\Program Files\Microchip\MPLAB C30\support\peripheral_24F) OpenSPI1 ( /* SPI1CON1 レジスタの設定 */ ENABLE_SCK_PIN & //内臓SPIクロック有効 0xefff /*Internal SPI clock is enabled */ ENABLE_SDO_PIN & //内臓モジュール(SDOピン)使用 0xf7ff /* SDO pin is used by module */ SPI_MODE16_ON & //通信単位: 16ビット 0x0400 /* Communication is word wide */ SPI_SMP_ON & //入力データを後段でサンプリングする 0xffff /* Input data sampled at end of data output time */ SPI_CKE_OFF & //出力データ変化の発生: アイドル→アクティブ変化時 0xfeff /* Transmit happens on transition from idle clock state to active clock state */ SLAVE_ENABLE_OFF & //SS1ピン使用せず 0xff7f /* Slave Select not used by module */ CLK_POL_ACTIVE_LOW & //クロックの極性選択: アイドル時Low、アクティブ時Low 0xffff /* Idle state for clock is high, active is low */ MASTER_ENABLE_ON & //マスターモード 0xffff /* Master Mode */ SEC_PRESCAL_1_1 & //2次プリスケーラ: 1:1 0xffff /* Secondary Prescale 1:1 */ PRI_PRESCAL_1_1 , //1次プリスケーア: 1:1 0xffff /* Primary Prescale 1:1 */ /*SPI2CON2 レジスタの設定 */ FRAME_ENABLE_OFF & //フレームSPIサポート: OFF 0x7fff /* Frame SPI support Disable */ FRAME_SYNC_INPUT & //フレーム同期パルスを入力とする 0xffff /* Frame sync pulse Input (slave) */ FRAME_POL_ACTIVE_HIGH & //フレーム同期パルスをアクティブHighにする 0xffff /* Frame sync pulse is active-high*/ FRAME_SYNC_EDGE_COINCIDE & // フレーム同期パルスを最初のビットと同期する0xffff /* Frame sync pulse coincides with first bit clock */ FIFO_BUFFER_ENABLE , //FIFOバッファー有効 0xffff /* FIFO buffer enabled */ /* SPI1STAT レジスタの設定 */ SPI_ENABLE & //SPIモジュール有効 0xffff /* Enable module */ SPI_IDLE_CON & //デバイスがアイドル時もモジュールは動作 0xdfff /* Continue module operation in idle mode */ SPI_RX_OVFLOW_CLR //受信オーバーフローフラグビットクリア 0xffbf /* Clear receive overflow bit.*/ ); SinTable(); //Sinのテーブル作成 ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_ON); //割込みレベル5、 タイマ1割込みON ConfigIntSPI1(SPI_INT_DIS & SPI_INT_PRI_6); //割り込みレベル6、 SPI割込みOFF EnableIntT1; //タイマ1割込み許可 while(1) { } CloseTimer1(); CloseSPI1(); return 0; }
<動作結果>
D/Aコンバータ MCP4822のVoutA(8番ピン)端子の出力電圧の波形を以下に示します。
出力電圧諸元
・周波数 : 277.5Hz (周期: 3.6msec = 10μsec ×360 )
・分解能 : 12ビット
・振幅(Vp-p) : 2.7V
・サンプリング周波数 : 100KHz
(測定器:デジタルオシロ 岩通 DS-5102)
12ビットD/Aコンバータへの書き込み <dsPIC C30編>
PICのSPIモジュールをSPI通信以外の別の目的で使用している場合などには、汎用ポートからSPI通信をする必要が
あります。以下にその例を紹介します。PIC18F452の例にMCP4822のクロックレベルの説明がありますので参照願い
ます。
<試作品の仕様>
・ 1msec毎に、1度毎の正弦関数値を計算しSPI通信でD/AコンバータMCP4822に伝送する。
・ MCP4822(電源電圧+5V)からは、0〜 4.096V、分解能12ビットの正弦波電圧を出力する。
出力される正弦波は周期360msec(周波数=2.78Hz)である。
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //******************************************************************* // 外付けDAコンバータMCP4822 (汎用ポート出力) // 正弦波出力 // サンプリング周波数:1KHz dsPIC30F4013 //******************************************************************* // MPLABのLink File // Linler Script : p30f4013.gld // Library File : libp30F4013-coff.a #include <p30f4013.h> #include <timer.h> #include "math.h" #define Clock 80000000 // 単位はHzで指定 _FOSC(CSW_FSCM_OFF & // クロック切り替えなし、フェールセイフクロックモニタなし XT_PLL8 //外部発振子周波数 × ポストスケーラ:1 × PLL:8倍 → 10MHz × 1 × 8 = 80MHz ); _FWDT(WDT_OFF); //ウォッチドックタイマ:OFF _FBORPOR(PBOR_ON & //ブラウンアウトリセット機能:ON BORV_42 & //ブラウンアウト電圧:4.2V PWRT_64 & //パワーオンリセットタイマ64msec MCLR_EN //MCLR機能:ON ); _FGS(CODE_PROT_OFF); //コードプロテクト:OFF unsigned int Angle = 0; // float PAI = 3.1416; int Chanel = 0; //出力チャンネル:A void DAout(unsigned int Out) { int i =0; LATDbits.LATD9 = 0; // clock low // RD9 : Clock(SCK) LATDbits.LATD8 = 0; // cs low (select) // RD8 : Chip Select(CS) LATDbits.LATD3 = Chanel; // VoutAに出力 0:Chanel A 1:Chanel B // RD3 : Data(SDI) LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low LATDbits.LATD3 = 1; //dumy LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low LATDbits.LATD3 = 0; //ゲイン設定ビット 1: G = 1 0: G = 2 // G = 2; V = Data/4096 * 2.048*2 [V] LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low LATDbits.LATD3 = 1; //シャットダウン設定ビット 1: 出力イネイブル 0: シャットダウン // output enable LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low for(i=0; i<12; i++) // 送信データをMSBから順次1ビットづつ出力する { if((Out & 0b0000100000000000) == 0)LATDbits.LATD3 = 0; else LATDbits.LATD3 = 1; Out = (Out << 1); LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low } LATDbits.LATD8 = 1; // cs high (MCP4822 Disable) } void _ISR _T1Interrupt(void) //1msec毎の割込み発生 { unsigned int Out; IFS0bits.T1IF = 0; //IFS0レジスタの T1IF(タイマ1の割込み検出)フラグリセット Out = (unsigned int)(4095*(1 + sinf(2*PAI*Angle/360))/2); //sinf():単精度 vs sin():倍精度 DAout(Out); Angle++; if(Angle >= 360)Angle = 0; } int main(void) { TRISD = 0; //ポートDを出力モードに設定 TRISF = 0; //タイマ1設定 OpenTimer1(T1_ON & //タイマ1ON T1_GATE_OFF & //ゲート制御off T1_PS_1_1 & //プリスケーラ 1/1 T1_SYNC_EXT_OFF & //クロック同期制御OFF T1_SOURCE_INT , //クロック源:内部クロック (unsigned int)(80000000/4/ 1000/1 - 1) // サンプリング周波数1KHz ); LATDbits.LATD8 = 0; //CS = 0; ConfigIntTimer1( T1_INT_ON & T1_INT_PRIOR_5 ); //タイマ1割込みON 割込みレベル5 EnableIntT1; //割込み許可 while(1) { } CloseTimer1(); return 0; }
<動作結果>
D/Aコンバータ MCP4822のVoutA(8番ピン)端子の出力電圧の波形を以下に示します。
出力電圧諸元
・周波数 : 2.78Hz( = 1000msec / 360msec)
・分解能 : 12ビット
・振幅(Vp-p) : 4.096V
・サンプリング周波数 : 1KHz
(測定器:デジタルオシロ 岩通 DS-5102)
12ビットD/Aコンバータへの書き込み <PIC32MX460F512L C32編>
SPI モジュールとして、 マイクロチップテクノロジーのD/AコンバータMCP4822をSPI通信で制御したD/A変換の例を紹介します。
<試作品の仕様>
・ PICで1度毎の正弦波テーブルを生成し、このデータを500KHzでサンプリングしてSPI通信でD/Aコンバータ
MCP4822に伝送する。
・ MCP4822(電源電圧+3.3V)からは、1.39KHz(注)、Vp-p 2.7V、分解能12ビットの正弦波電圧を出力する。
(注)1.39KHz = 500KHz ÷ 360
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
・ QFPのPIC32MX460F512Lは、マイクロチップから開発用ターゲットボードExplore 16のCPUボードとして、販売されている
PIM(Plug in Moduke)に実装されているものを使っています。
・使用しているユニバーサルキバンは自作のユニバーサルキバンです。
<プログラム例> ///************************************************************/ // SPI通信による正弦波出力 // サンプリング周波数:500KHz 出力正弦波 12bit 1.39 KHz // PC32MX460F512L + MCP4822 //************************************************************/ #include <plib.h> // PIC32 peripheral library //for SYSTEMConfigPerformance() //#include "math.h" //math.hは plib.hの含まれている // コンフィギュレーション設定 // CPU=80MHz Peri=80MHz,HS+PLL,Divider=1/2,PLL=x20,WDT=Off #pragma config FNOSC=PRIPLL, POSCMOD=HS, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_1 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 int Clock = 80000000; //80MHz short int sinValue[360]; //sinテーブル値 RAM容量が少ないので大きな値(例1000)をとると不可解な現象がでる short int angleValue = 0; // float PAI = 3.1416; void __ISR(4,ipl2)T1Hander(void) //タイマ1割込 2μsec毎 { short int temp; mT1ClearIntFlag(); //タイマ1 フラグクリア LATDbits.LATD11 = 0; //CS = 0 WriteSPI1(sinValue[angleValue] | 0b0001000000000000); //VoutAにゲイン2で出力 //MCP4822への書き込みコマンド //bit15(書き込みレジスタ選択) 1:VoutB 0:VoutA //bit14(予備) //bit13(出力ゲイン選択) 1:1倍 0:2倍 //bit12(出力オフ制御) 1:出力ON 0:出力OFF //bit11〜bit0 データ MSBから順次送信される angleValue++; if(angleValue >= 360)angleValue = 0; //1μsec delay ( Nop()0.05μsec ×20個 = 1μsec ) // 0.2μsec以下NG Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop(); LATDbits.LATD11 = 1; //CS = 1 → CSの立ち上がりエッジでMCP4822の出力レジスタに送信データがラッチされる } void SinTable() //Sin のテーブル作成 { short int i; int value; for(i = 0; i < 360; i++) { value = (1 + sinf(2*PAI*i/360))/2*4095*3.3/5; //sinf():単精度 vs sin():倍精度 if( value < 0) value = 0; sinValue[i] = (short int)value; //Vout = 2.048×2×Dn/4095 Vout(max) = 4.096[V] ( > 3.3V(電源電圧)) 4.096×3.3/5 = 2.7V (< (3.3V時オペアンプ飽和電圧)) } } int main(void) { SYSTEMConfigPerformance(80000000); // システム最適化 mJTAGPortEnable(DEBUG_JTAGPORT_OFF); TRISD = 0x00000000; //SCK1/RD10、SDO1/RD0 (CS)RD11 の各ポートを出力モードに設定 OpenTimer1 ( T1_ON | // タイマ1 イネーブル //T1_OFF → タイマ1 ディセーブル T1_SOURCE_INT | //クロックソース:インターナル //T1_SOURCE_EXT → 外部発振器 T1_PS_1_1, //プリスケール 1/256 //1/1、1/2、1/4、1/8、1/16、1/32、1/64、1/256 160 //PRx値:800 → T0[μsec] = 1000000/80000000*1*200 = 2.0 μsec //PICMX32は1クロックで1命令 //周期 T0[sec] = 1/Fosc × プリスケーラの逆数 × PRx値 ); SpiChnOpen ( 1, //有効化チャンネル: チャンネル1 SPICON_MSTEN | //マスターモード有効化 //Master mode Enable // SPICON_CKP | //クロック極性制御有 //Clock Polarity control // SPICON_SSEN | //SSピン制御:有 //Slave Select pin control SPICON_CKE | //★★ クロックエッジ制御: イネーブル// クロックがActive→idleに変化した時データ変化 //Clock Edge control SPICON_SMP | //データ抽出タイミング: データの後縁 //Sample phase control SPICON_MODE16 | //データ幅: 16ビット //Character width control // SPICON_DISSDO | //SDOピン制御: 無 (SDOポートをSPIモジュールとして使用しない) //SDO pin control // SPICON_SIDL | //アイドル時CPU動作: 停止 //idle functinality control // SPICON_FRZ | //デバッグ例外モード動作: 停止//debug functionality control SPICON_ON, //SPI制御: 有効 //Module ON control // SPICON_SPIFE | //フレーム同期パルスエッジ: 第一パルスと一致 //Frame Sync edge control // SPICON_FRMPOL | //フレーム制御: Active High //Frame Sync Polality control // SPICON_FRMSYNC | //フレーム同期パルス: 入力 //Frame Sync Direction control // SPICON_FRMEN | //フレームモード: 有効 //Frame Mode enable 4 //fpbDiv = 4 → SPIクロック周波数:20MHz (=80MHz(システムクロック周波数)÷1(Postscaler div:FPBDIV=DIV_1)÷4) ////fpbDiv: Fpbclk(ペリフェラルバスクロック周波数)の分周比で2〜1024の値 //fpbDiv = 2 × (SPIxBRG<8:0> + 1) //SPIクロック周波数 = Fpbclk / fpbDiv // = Fpbclk / ( 2 ×(SPIxBRG<8:0> + 1)) ); LATDbits.LATD11 = 1; //CS = 1 SinTable(); //Sinのテーブル作成 ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_2); //タイマ1割込ON、割り込みレベル2 INTEnableSystemMultiVectoredInt(); //割り込みをマルチベクタモードで許可 while(1) //割り込みを待つ { } }
<動作結果>
D/Aコンバータ MCP4822のVoutA(8番ピン)端子の出力電圧の波形を以下に示します。
出力電圧諸元
・周波数 : 1.39KHz( = 1000msec / 360msec)
・分解能 : 12ビット
・振幅(Vp-p) : 2.7V
・サンプリング周波数 : 500KHz
(測定器:デジタルオシロ 岩通 DS-5102)
12ビットD/Aコンバータへの書き込み <PIC32MZ2048ECH100 Harmony + XC32編>
SPI モジュールとして、 マイクロチップテクノロジーのD/AコンバータMCP4822をSPI通信で制御したD/A変換の例を紹介します。
<試作品の仕様>
・ PICで1度毎の正弦波テーブルを生成し、このデータを500KHzでサンプリングしてSPI通信でD/Aコンバータ
MCP4822に伝送する。
・ MCP4822(電源電圧+3.3V)からは、1.39KHz(注)、Vp-p 2.7V、分解能12ビットの正弦波電圧を出力する。
(注)1.39KHz = 500KHz ÷ 360
・ 開発環境 …… Harmony: ver. 1.00 XC32: ver.1.33 MPLABX: ver.2.25 PIC32MZ2048ECH100:
revision 5
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //以下、main.c //------------------------------------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony Project Main Source File Company: Microchip Technology Inc. File Name: main.c Summary: This file contains the "main" function for an MPLAB Harmony project. Description: This file contains the "main" function for an MPLAB Harmony project. The "main" function calls the "SYS_Initialize" function to initialize the state machines of all MPLAB Harmony modules in the system and it calls the "SYS_Tasks" function from within a system-wide "super" loop to maintain their correct operation. These two functions are implemented in configuration-specific files (usually "system_init.c" and "system_tasks.c") in a configuration-specific folder under the "src/system_config" folder within this project's top-level folder. An MPLAB Harmony project may have more than one configuration, each contained within it's own folder under the "system_config" folder. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. //Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include <stddef.h> // Defines NULL #include <stdbool.h> // Defines true #include <stdlib.h> // Defines EXIT_FAILURE #include "system/common/sys_module.h" // SYS function prototypes // ***************************************************************************** // ***************************************************************************** // Section: Main Entry Point // ***************************************************************************** // ***************************************************************************** int main ( void ) { /* Initialize all MPLAB Harmony modules, including application(s). */ SYS_Initialize ( NULL ); while ( true ) { /* Maintain state machines of all polled MPLAB Harmony modules. */ SYS_Tasks ( ); } /* Execution should not come here during normal operation */ return ( EXIT_FAILURE ); } /******************************************************************************* End of File */ //以下、sysytem_config.h //------------------------------------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony System Configuration Header File Name: system_config.h Summary: Build-time configuration header for the system defined by this MPLAB Harmony project. Description: An MPLAB Project may have multiple configurations. This file defines the build-time options for a single configuration. Remarks: This configuration header must not define any prototypes or data definitions (or include any files that do). It only provides macro definitions for build-time configuration options that are not instantiated until used by another MPLAB Harmony module or application. Created with MPLAB Harmony Version 1.00 *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END #ifndef _SYSTEM_CONFIG_H #define _SYSTEM_CONFIG_H // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** /* This section Includes other configuration headers necessary to completely define this configuration. */ // ***************************************************************************** // ***************************************************************************** // Section: System Service Configuration // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* Clock System Service Configuration Options */ #define SYS_CLK_SOURCE SYS_CLK_SOURCE_PRIMARY_SYSPLL #define SYS_CLK_FREQ 200000000ul #define SYS_CLK_CONFIG_PRIMARY_XTAL 24000000ul #define SYS_CLK_CONFIG_SECONDARY_XTAL 32768ul #define SYS_CLK_CONFIG_SYSPLL_INP_DIVISOR 8 #define SYS_CLK_CONFIG_FREQ_ERROR_LIMIT 10 #define SYS_CLK_CONFIGBIT_USBPLL_ENABLE true #define SYS_CLK_CONFIG_USB_CLOCK 24000000ul #define SYS_CLK_WAIT_FOR_SWITCH true #define SYS_CLK_KEEP_SECONDARY_OSC_ENABLED true #define SYS_CLK_ON_WAIT OSC_ON_WAIT_IDLE /*** Common System Service Configuration ***/ #define SYS_BUFFER false #define SYS_QUEUE false // ***************************************************************************** /* Device Control System Service Configuration Options */ #define SYS_DEVCON_SYSTEM_CLOCK 200000000 /*** Interrupt System Service Configuration ***/ #define SYS_INT true // ***************************************************************************** // ***************************************************************************** // Section: Driver Configuration // ***************************************************************************** // ***************************************************************************** /*** Timer Driver Configuration ***/ #define DRV_TMR_INTERRUPT_SOURCE_IDX0 INT_SOURCE_TIMER_1 /*** SPI Driver Configuration ***/ /*** Driver Compilation and static configuration options. ***/ /*** Select SPI compilation units.***/ #define DRV_SPI_ISR 0 #define DRV_SPI_POLLED 1 #define DRV_SPI_MASTER 1 #define DRV_SPI_SLAVE 0 #define DRV_SPI_RM 0 #define DRV_SPI_EBM 1 #define DRV_SPI_8BIT 0 #define DRV_SPI_16BIT 1 #define DRV_SPI_32BIT 0 #define DRV_SPI_DMA 0 /*** SPI Driver Static Allocation Options ***/ #define DRV_SPI_INSTANCES_NUMBER 1 #define DRV_SPI_CLIENTS_NUMBER 1 #define DRV_SPI_ELEMENTS_PER_QUEUE 10 /*** SPI Driver Index 0 configuration ***/ #define DRV_SPI_SPI_ID_IDX0 SPI_ID_4 //SPIチャンネル4を設定 #define DRV_SPI_TASK_MODE_IDX0 DRV_SPI_TASK_MODE_POLLED #define DRV_SPI_SPI_MODE_IDX0 DRV_SPI_MODE_MASTER //マスターモード #define DRV_SPI_ALLOW_IDLE_RUN_IDX0 false #define DRV_SPI_SPI_PROTOCOL_TYPE_IDX0 DRV_SPI_PROTOCOL_TYPE_STANDARD //標準モード #define DRV_SPI_COMM_WIDTH_IDX0 SPI_COMMUNICATION_WIDTH_16BITS //データ幅: 16ビット #define DRV_SPI_SPI_CLOCK_IDX0 CLK_BUS_PERIPHERAL_2 //クロックそーし PBCLK2 #define DRV_SPI_BAUD_RATE_IDX0 1000000 //ボーレート: 1MHz #define DRV_SPI_BUFFER_TYPE_IDX0 DRV_SPI_BUFFER_TYPE_ENHANCED //バッファー:エンハンスト #define DRV_SPI_CLOCK_MODE_IDX0 DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_FALL //アイドル時:Low //検出エッジ: 立下り #define DRV_SPI_INPUT_PHASE_IDX0 SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE //検出位相: 中央部 #define DRV_SPI_TX_INT_SOURCE_IDX0 INT_SOURCE_SPI_4_TRANSMIT #define DRV_SPI_RX_INT_SOURCE_IDX0 INT_SOURCE_SPI_4_RECEIVE #define DRV_SPI_ERROR_INT_SOURCE_IDX0 INT_SOURCE_SPI_4_ERROR #define DRV_SPI_QUEUE_SIZE_IDX0 10 #define DRV_SPI_RESERVED_JOB_IDX0 1 // ***************************************************************************** // ***************************************************************************** // Section: Middleware & Other Library Configuration // ***************************************************************************** // ***************************************************************************** #endif // _SYSTEM_CONFIG_H /******************************************************************************* End of File */ //以下、appp.c //--------------------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony Application Source File Company: Microchip Technology Inc. File Name: app.c Summary: This file contains the source code for the MPLAB Harmony application. Description: This file contains the source code for the MPLAB Harmony application. It implements the logic of the application's state machine and it may call API routines of other MPLAB Harmony modules in the system, such as drivers, system services, and middleware. However, it does not call any of the system interfaces (such as the "Initialize" and "Tasks" functions) of any of the modules in the system or make any assumptions about when those functions are called. That is the responsibility of the configuration-specific system files. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include "app.h" #include "math.h" short int sinValue[360]; //sinテーブル値 int delay_Clock = 200000000; //200MHz void delay_us(volatile unsigned int usec) //1μsec遅延 { volatile int count; count = (int)(delay_Clock/20000000)*usec; do //実測 at 200MH (Clock=200000000) { //delay_us(1000):1000.4μsec delay_us(100):100.6μsec delay_us(10):10.5μsec delay_us(1):1.5μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void delay_ms(volatile unsigned int msec) //1msec遅延 { volatile unsigned int i; //実測:at200MH (Clock=200000000)//delay_ms(1): 1.0006msec delay_ms(100):100.04msec for(i=0; i<msec; i++) delay_us(1000); } void SinTable() //Sin のテーブル作成 { short int i; float PAI = 3.1416; int value; for(i = 0; i < 360; i++) { value = (1 + sinf(2*PAI*i/360))/2*4095*3.3/5; //sinf():単精度 vs sin():倍精度 if( value < 0) value = 0; sinValue[i] = (short int)value; //Vout = 2.048×2×Dn/4095 Vout(max) = 4.096[V] ( > 3.3V(電源電圧)) 4.096×3.3/5 = 2.7V (< (3.3V時オペアンプ飽和電圧)) } } // ***************************************************************************** // ***************************************************************************** // Section: Global Data Definitions // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* Application Data Summary: Holds application data Description: This structure holds the application's data. Remarks: This structure should be initialized by the APP_Initialize function. Application strings and buffers are be defined outside this structure. */ APP_DATA appData; // ***************************************************************************** // ***************************************************************************** // Section: Application Callback Functions // ***************************************************************************** // ***************************************************************************** /* TODO: Add any necessary callback funtions. */ // ***************************************************************************** // ***************************************************************************** // Section: Application Local Functions // ***************************************************************************** // ***************************************************************************** /* TODO: Add any necessary local functions. */ // ***************************************************************************** // ***************************************************************************** // Section: Application Initialization and State Machine Functions // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void APP_Initialize ( void ) Remarks: See prototype in app.h. */ void APP_Initialize ( void ) { /* Place the App state machine in its initial state. */ appData.state = APP_STATE_INIT; /* TODO: Initialize your application's state machine and other * parameters. */ PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_D, 10 ); //TRISDbits.TRISD10 = 0; //RD10: out --> SCK4端子出力ポートに設定 PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_D, 11 ); //TRISDbits.TRISD11 = 0; //RD11: out --> SDO4端子出力ポートに設定 PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_A, 14 ); //TRISAbits.TRISA14 = 0; //RA14: out --> CS制御(MP4822) PLIB_SPI_Enable(SPI_ID_4); //SPI4CONbits.ON = 1; //SPI4 イネーブル SinTable(); //Sin波形テーブル作成 //1deg毎 } /****************************************************************************** Function: void APP_Tasks ( void ) Remarks: See prototype in app.h. */ void APP_Tasks ( void ) { /* Check the application's current state. */ switch ( appData.state ) { /* Application's initial state. */ case APP_STATE_INIT: { break; } /* TODO: implement your application state machine.*/ /* The default state should never be executed. */ default: { /* TODO: Handle error in application's state machine. */ break; } } } /******************************************************************************* End of File */ //以下、system_init.c //-------------------------------------------------------------------------------------------------------------- /******************************************************************************* System Initialization File File Name: system_init.c Summary: This file contains source code necessary to initialize the system. Description: This file contains source code necessary to initialize the system. It implements the "SYS_Initialize" function, configuration bits, and allocates any necessary global system resources, such as the systemObjects structure that contains the object handles to all the MPLAB Harmony module objects in the system. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include "system_config.h" #include "app.h" #include "system_definitions.h" // **************************************************************************** // **************************************************************************** // Section: Configuration Bits // **************************************************************************** // **************************************************************************** //----------------------------------------------------------------------- //DEVCFG0レジスタ #pragma config EJTAGBEN = NORMAL #pragma config DBGPER = ALLOW_PG2 #pragma config FSLEEP = OFF #pragma config FECCCON = OFF_UNLOCKED #pragma config BOOTISA = MIPS32 #pragma config TRCEN = OFF #pragma config ICESEL = ICS_PGx2 #pragma config JTAGEN = OFF //JTAG ポート Disable #pragma config DEBUG = OFF //---------------------------------------------------------------------- //DEVCFG1レジスタ #pragma config FNOSC = SPLL //PLL回路(システムPLL)選択 //システム発振回路 //内蔵FRC(8MHz)選択の場合:FNOSC = FRCDIV //Oscillator Selection Bits (Fast RC Osc w/Div-by-N (FRCDIV)) #pragma config FDMTEN = OFF //デッドマンタイマ OFF (Deadman Timer is disabled) //#pragma config DMTINTV = WIN_127_128 // DMT Count Window Interval (Window/Interval value is 127/128 counter value) #pragma config FSOSCEN = OFF // 副発振器OFF //Secondary Oscillator Enable (Disable SOSC) #pragma config IESO = OFF //ウェイクアップ時の2段速度スタートアップ // Internal/External Switch Over (Disabled) #pragma config POSCMOD = HS //HS: ハイスピードレゾネータモード // HS(High Speed Resonator Operation) Oscillator mode selected //EC: 外部発振器 //EC(External Clock Input Operation) mode selected // Primary Oscillator Configuration (Primary osc disabled) #pragma config OSCIOFNC = OFF //OSCCOピン出力無効 #pragma config FCKSM = CSECME //クロック発振:切替及びモニタ有効 //主発振器失陥でFRC(内蔵高速発振器)に切替 //FSCM(Fail Safe Clock Monitor)制御 #pragma config FWDTEN = OFF // ウォッチドックタイマ OFF //Watchdog Timer Disable //#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576) //#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming) //#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode) //#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%) //-------------------------------------------------------------------------------------------------------------------- // DEVCFG2レジスタ //システムクロック:200MHz //ペリフェラル周波数://default: 100MHz //PBxDIVで8系統毎に設定変更可 //PBxDIV: PERIPHERAL BUS CLOCK DIVISOR CONTROL レジスタのPBDIV<6:0>: Peripheral Bus Clock Divisor Control ビットで設定 #pragma config FPLLRNG = RANGE_13_26_MHZ //PLL Input周波数入力範囲設定// System PLL Input Range (13-26 MHz Input) //24MHz故 #pragma config FPLLIDIV = DIV_3 //PLL入力側での分周: 1/3 // PLL Input周波数 = 24MHz ÷ 3 = 8MHz // System PLL Input Divider (1x Divider) //#pragma config FPLLICLK = PLL_POSC //主発振回路選択 //内蔵FRC(8MHz)の場合はFPLLICLK = PLL_FRC// System PLL Input Clock Selection (POSC is input to the System PLL) #pragma config FPLLICLK = PLL_FRC //内蔵高速発振器選択 //★★★ バグ有 主発振回路選択の時、FPLLICLK = PLL_POSCではなくFPLLICLK = PLL_FRCを選択する。(at ver.1.33 XC32) #pragma config FPLLMULT = MUL_50 //PLL倍率:50倍 //8MHz x 50 = 400MHz //System PLL Multiplier (PLL Multiply by 50) #pragma config FPLLODIV = DIV_2 //PLL出力側での分周: 1/2 //システムクロック = 400MHz ÷ 2 = 200MHz #pragma config UPLLFSEL = FREQ_24MHZ //USBのPLL入力を 24MHz→12MHzに変換 // USB PLL Input Frequency Selection (USB PLL input is 12 MHz) #pragma config UPLLEN = ON //USBのPLL変換:イネーブル // USB PLL Enable (USB PLL is enabled) //-------------------------------------------------------------------------------------------------------------------------- //DEVCFG3レジスタ #pragma config USERID = 0xffff #pragma config FMIIEN = ON #pragma config FETHIO = ON #pragma config PGL1WAY = ON #pragma config PMDL1WAY = ON #pragma config IOL1WAY = ON #pragma config FUSBIDIO = ON /*** BF1SEQ0 ***/ #pragma config TSEQ = 0xffff #pragma config CSEQ = 0xffff // ***************************************************************************** // ***************************************************************************** // Section: Library/Stack Initialization Data // ***************************************************************************** // *****************************************************************************/ // ***************************************************************************** // ***************************************************************************** // Section: Driver Initialization Data // ***************************************************************************** // ***************************************************************************** /*** SPI Driver Initialization Data ***/ /*** Index 0 ***/ DRV_SPI_INIT drvSpi0InitData = //SPI4オブジェクト初期化 { .spiId = DRV_SPI_SPI_ID_IDX0, .taskMode = DRV_SPI_TASK_MODE_IDX0, .spiMode = DRV_SPI_SPI_MODE_IDX0, .allowIdleRun = DRV_SPI_ALLOW_IDLE_RUN_IDX0, .spiProtocolType = DRV_SPI_SPI_PROTOCOL_TYPE_IDX0, .commWidth = DRV_SPI_COMM_WIDTH_IDX0, .spiClk = DRV_SPI_SPI_CLOCK_IDX0, .baudRate = DRV_SPI_BAUD_RATE_IDX0, .bufferType = DRV_SPI_BUFFER_TYPE_IDX0, .clockMode = DRV_SPI_CLOCK_MODE_IDX0, .inputSamplePhase = DRV_SPI_INPUT_PHASE_IDX0, .queueSize = DRV_SPI_QUEUE_SIZE_IDX0, .jobQueueReserveSize = DRV_SPI_RESERVED_JOB_IDX0, }; // ***************************************************************************** // ***************************************************************************** // Section: System Data // ***************************************************************************** // ***************************************************************************** /* Structure to hold the object handles for the modules in the system. */ SYSTEM_OBJECTS sysObj; // ***************************************************************************** // ***************************************************************************** // Section: Module Initialization Data // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* System Clock Initialization Data */ const SYS_CLK_INIT sysClkInit = { .moduleInit = {0}, .systemClockSource = SYS_CLK_SOURCE, .systemClockFrequencyHz = SYS_CLK_FREQ, .waitTillComplete = true, .secondaryOscKeepEnabled = true, .onWaitInstruction = SYS_CLK_ON_WAIT, }; /*** System Device Control Initialization Data ***/ const SYS_DEVCON_INIT sysDevconInit = { .moduleInit = {0}, }; // ***************************************************************************** // ***************************************************************************** // Section: Static Initialization Functions // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void DRV_TMR0_Initialize(void) Summary: Initializes Timer Driver Instance 0 Remarks: */ void DRV_TMR0_Initialize(void) //タイマ1初期設定 { /* Setup TMR0 Instance */ PLIB_TMR_Stop(TMR_ID_1); /* Disable Timer */ PLIB_TMR_ClockSourceSelect(TMR_ID_1, TMR_CLOCK_SOURCE_PERIPHERAL_CLOCK); /* Select clock source */ PLIB_TMR_PrescaleSelect(TMR_ID_1, TMR_PRESCALE_VALUE_8); /* Select prescalar value */ // PLIB_TMR_PrescaleSelect(TMR_ID_1, TMR_PRESCALE_VALUE_256); /* Select prescalar value */ PLIB_TMR_Mode16BitEnable(TMR_ID_1); /* Enable 16 bit mode */ PLIB_TMR_Counter16BitClear(TMR_ID_1); /* Clear counter */ /* Setup Interrupt */ PLIB_INT_SourceEnable(INT_ID_0, INT_SOURCE_TIMER_1); PLIB_INT_VectorPrioritySet(INT_ID_0, INT_VECTOR_T1, INT_PRIORITY_LEVEL1); PLIB_INT_VectorSubPrioritySet(INT_ID_0, INT_VECTOR_T1, INT_SUBPRIORITY_LEVEL2); PLIB_TMR_Period16BitSet(TMR_ID_1,39063); //5 nsec x2 x 39063 x 8 = 100.0128msec = 100msec PLIB_TMR_Start(TMR_ID_1); //タイマスタート } // ***************************************************************************** // ***************************************************************************** // Section: System Initialization // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void SYS_Initialize ( SYS_INIT_DATA *data ) Summary: Initializes the board, services, drivers, application and other modules. Remarks: See prototype in system/common/sys_module.h. */ void SYS_Initialize ( void* data ) { /* Core Processor Initialization */ SYS_CLK_Initialize(&sysClkInit); sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit); SYS_DEVCON_PerformanceConfig(SYS_DEVCON_SYSTEM_CLOCK); /* System Services Initialization */ SYS_INT_Initialize(); /* Initialize Drivers */ /* Timer Instanace 0 Call */ DRV_TMR0_Initialize(); /*** SPI Driver Index 0 initialization***/ //SPI4用 リマップ RPD11Rbits.RPD11R = 0b1000; //RD11ピンに SDO4の出力を割り付け sysObj.spiObjectIdx0 = DRV_SPI_Initialize(0, (const SYS_MODULE_INIT * const)&drvSpi0InitData); /* Initialize System Services */ /* Initialize Middleware */ /* Enable Global Interrupts */ SYS_INT_Enable(); /* Initialize the Application */ APP_Initialize(); } /******************************************************************************* End of File */ //以下、system_interrupt.c //-------------------------------------------------------------------------------------------------------------- /******************************************************************************* System Interrupts File File Name: system_int.c Summary: Raw ISR definitions. Description: This file contains a definitions of the raw ISRs required to support the interrupt sub-system. Summary: This file contains source code for the interrupt vector functions in the system. Description: This file contains source code for the interrupt vector functions in the system. It implements the system and part specific vector "stub" functions from which the individual "Tasks" functions are called for any modules executing interrupt-driven in the MPLAB Harmony system. Remarks: This file requires access to the systemObjects global data structure that contains the object handles to all MPLAB Harmony module objects executing interrupt-driven in the system. These handles are passed into the individual module "Tasks" functions to identify the instance of the module to maintain. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2011-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include <xc.h> #include <sys/attribs.h> #include "app.h" #include "system_definitions.h" # ifndef _MY_INCLUDE_PERIPHERAL #define _MY_INCLUDE_PERIPHERAL #include <peripheral/peripheral.h> #include <peripheral/ports/plib_ports.h> #endif int IntervalCount = 0; short int angleValue = 0; extern short int sinValue[360]; //sinテーブル値 // ***************************************************************************** // ***************************************************************************** // Section: System Interrupt Vector Functions // ***************************************************************************** // ***************************************************************************** void __ISR(_TIMER_1_VECTOR, ipl2) _IntHandlerDrvTmrInstance0(void) { PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_1); // IFS0bits.T1IF= 0; //タイマ1割り込みフラグクリア LATAbits.LATA14 = 0; //MCP4822 CS = 0 PLIB_TMR_Period16BitSet(TMR_ID_1,25000); //5 nsec x2 x 25000 x 8 = 10000nsec = 1000μsec = 2msec PLIB_SPI_BufferWrite16bit ( SPI_ID_4, (short int)(sinValue[angleValue] | 0b0001000000000000)); // SPI4BUF = (short int)(sinValue[angleValue] | 0b0001000000000000); //送信データ送信 //MP4822 制御コマンド //VoutAにゲイン2で出力 //MCP4822への書き込みコマンド //bit15(書き込みレジスタ選択) 1:VoutB 0:VoutA //bit14(予備) //bit13(出力ゲイン選択) 1:1倍 0:2倍 //bit12(出力オフ制御) 1:出力ON 0:出力OFF //bit11?bit0 データ MSBから順次送信される while(PLIB_SPI_IsBusy(SPI_ID_4)); //書込み完了をまつ // while(SPI4STATbits.SPITBF); //: SPI Transmit Buffer Full Status bit //SPI2SRレジスタへの書込み完了 angleValue++; if(angleValue >= 360)angleValue = 0; delay_us(200); LATAbits.LATA14 = 1; //MCP4822 CS = 1; } /******************************************************************************* End of File */
<動作結果>
D/Aコンバータ MCP4822のVoutA(8番ピン)端子の出力電圧の波形を以下に示します。
出力電圧諸元
・周波数 : 1.39KHz( = 1000msec / 360msec)
・分解能 : 12ビット
・振幅(Vp-p) : 2.7V
・サンプリング周波数 : 500KHz
(測定器:デジタルオシロ 岩通 DS-5102)
★ フラッシュメモリ 読み書き
<PIC32MZ2048ECH100 Harmony + XC32編>
SPIインターフェース フラッシュメモリへの読み書きの例を紹介します。
<試作品の仕様>
・ SPIインターフェースをもつフラッシュメモリへの読み書きをおこなう
・ フラッシュメモリは マイクロチップのSST25VF016(メモリ容量: 16Mビット)とする
・ マイコンが立ち上がったら フラッシュメモリに 以下の文字列を順次書込む
@ Hellow World
A PIC32MZ Run
B SPI Flash
・ その後、書き込んだ文字列を順次読みだして キャラクタ液晶に表示する。
表示は以下の要領で行う
@ 上段: 1st
下段: Str=Hellow World
A 上段: 2nd
下段: Str=PIC32MZ Run
B 上段: 3rd
下段: Str=SPI Flash
・ 開発環境 …… Harmony: ver. 1.00 XC32: ver.1.33 MPLABX: ver.2.25 PIC32MZ2048ECH100:
revision 5
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //以下、main.c //--------------------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony Project Main Source File Company: Microchip Technology Inc. File Name: main.c Summary: This file contains the "main" function for an MPLAB Harmony project. Description: This file contains the "main" function for an MPLAB Harmony project. The "main" function calls the "SYS_Initialize" function to initialize the state machines of all MPLAB Harmony modules in the system and it calls the "SYS_Tasks" function from within a system-wide "super" loop to maintain their correct operation. These two functions are implemented in configuration-specific files (usually "system_init.c" and "system_tasks.c") in a configuration-specific folder under the "src/system_config" folder within this project's top-level folder. An MPLAB Harmony project may have more than one configuration, each contained within it's own folder under the "system_config" folder. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. //Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include <stddef.h> // Defines NULL #include <stdbool.h> // Defines true #include <stdlib.h> // Defines EXIT_FAILURE #include "system/common/sys_module.h" // SYS function prototypes // ***************************************************************************** // ***************************************************************************** // Section: Main Entry Point // ***************************************************************************** // ***************************************************************************** int main ( void ) { /* Initialize all MPLAB Harmony modules, including application(s). */ SYS_Initialize ( NULL ); while ( true ) { /* Maintain state machines of all polled MPLAB Harmony modules. */ SYS_Tasks ( ); } /* Execution should not come here during normal operation */ return ( EXIT_FAILURE ); } /******************************************************************************* End of File */ //以下、system_config.h //-------------------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony System Configuration Header File Name: system_config.h Summary: Build-time configuration header for the system defined by this MPLAB Harmony project. Description: An MPLAB Project may have multiple configurations. This file defines the build-time options for a single configuration. Remarks: This configuration header must not define any prototypes or data definitions (or include any files that do). It only provides macro definitions for build-time configuration options that are not instantiated until used by another MPLAB Harmony module or application. Created with MPLAB Harmony Version 1.00 *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END #ifndef _SYSTEM_CONFIG_H #define _SYSTEM_CONFIG_H // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** /* This section Includes other configuration headers necessary to completely define this configuration. */ // ***************************************************************************** // ***************************************************************************** // Section: System Service Configuration // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* Clock System Service Configuration Options */ #define SYS_CLK_SOURCE SYS_CLK_SOURCE_PRIMARY_SYSPLL #define SYS_CLK_FREQ 200000000ul #define SYS_CLK_CONFIG_PRIMARY_XTAL 24000000ul #define SYS_CLK_CONFIG_SECONDARY_XTAL 32768ul #define SYS_CLK_CONFIG_SYSPLL_INP_DIVISOR 8 #define SYS_CLK_CONFIG_FREQ_ERROR_LIMIT 10 #define SYS_CLK_CONFIGBIT_USBPLL_ENABLE true #define SYS_CLK_CONFIG_USB_CLOCK 24000000ul #define SYS_CLK_WAIT_FOR_SWITCH true #define SYS_CLK_KEEP_SECONDARY_OSC_ENABLED true #define SYS_CLK_ON_WAIT OSC_ON_WAIT_IDLE /*** Common System Service Configuration ***/ #define SYS_BUFFER false #define SYS_QUEUE false // ***************************************************************************** /* Device Control System Service Configuration Options */ #define SYS_DEVCON_SYSTEM_CLOCK 200000000 /*** Interrupt System Service Configuration ***/ #define SYS_INT true // ***************************************************************************** // ***************************************************************************** // Section: Driver Configuration // ***************************************************************************** // ***************************************************************************** /*** Timer Driver Configuration ***/ #define DRV_TMR_INSTANCES_NUMBER 1 #define DRV_TMR_CLIENTS_NUMBER 1 #define DRV_TMR_INTERRUPT_MODE true #define DRV_TMR_PERIPHERAL_ID_IDX0 TMR_ID_1 #define DRV_TMR_INTERRUPT_SOURCE_IDX0 INT_SOURCE_TIMER_1 #define DRV_TMR_INTERRUPT_VECTOR_IDX0 INT_VECTOR_T1 #define DRV_TMR_ISR_VECTOR_IDX0 _TIMER_1_VECTOR #define DRV_TMR_INTERRUPT_PRIORITY_IDX0 INT_PRIORITY_LEVEL1 #define DRV_TMR_INTERRUPT_SUB_PRIORITY_IDX0 INT_SUBPRIORITY_LEVEL0 #define DRV_TMR_CLOCK_SOURCE_IDX0 DRV_TMR_CLKSOURCE_INTERNAL #define DRV_TMR_PRESCALE_IDX0 TMR_PRESCALE_VALUE_256 #define DRV_TMR_OPERATION_MODE_IDX0 DRV_TMR_OPERATION_MODE_16_BIT #define DRV_TMR_ASYNC_WRITE_ENABLE_IDX0 false #define DRV_TMR_POWER_STATE_IDX0 SYS_MODULE_POWER_RUN_FULL /*** SPI Driver Configuration ***/ /*** Driver Compilation and static configuration options. ***/ /*** Select SPI compilation units.***/ #define DRV_SPI_ISR 0 #define DRV_SPI_POLLED 1 #define DRV_SPI_MASTER 1 #define DRV_SPI_SLAVE 0 #define DRV_SPI_RM 0 #define DRV_SPI_EBM 1 #define DRV_SPI_8BIT 1 #define DRV_SPI_16BIT 0 #define DRV_SPI_32BIT 0 #define DRV_SPI_DMA 0 /*** SPI Driver Static Allocation Options ***/ #define DRV_SPI_INSTANCES_NUMBER 1 #define DRV_SPI_CLIENTS_NUMBER 1 #define DRV_SPI_ELEMENTS_PER_QUEUE 10 /*** SPI Driver Index 0 configuration ***/ #define DRV_SPI_SPI_ID_IDX0 SPI_ID_1 #define DRV_SPI_TASK_MODE_IDX0 DRV_SPI_TASK_MODE_POLLED #define DRV_SPI_SPI_MODE_IDX0 DRV_SPI_MODE_MASTER //マスターモード #define DRV_SPI_ALLOW_IDLE_RUN_IDX0 false #define DRV_SPI_SPI_PROTOCOL_TYPE_IDX0 DRV_SPI_PROTOCOL_TYPE_STANDARD //SPIプリトコル 標準 #define DRV_SPI_COMM_WIDTH_IDX0 SPI_COMMUNICATION_WIDTH_8BITS //データ幅 8ビット #define DRV_SPI_SPI_CLOCK_IDX0 CLK_BUS_PERIPHERAL_2 //クロック源 PBCLK2 #define DRV_SPI_BAUD_RATE_IDX0 1000000 //SPIクロック 1MHz #define DRV_SPI_BUFFER_TYPE_IDX0 DRV_SPI_BUFFER_TYPE_ENHANCED #define DRV_SPI_CLOCK_MODE_IDX0 DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_FALL //SPI4CONbits.CKP = 0; //クロックの極性: アイドル時 = Low、 アクティブ = High //SPI4CONbits.CKE = 1; //クロックがActive→idleに変化した時データ変化 #define DRV_SPI_INPUT_PHASE_IDX0 SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE #define DRV_SPI_TX_INT_SOURCE_IDX0 INT_SOURCE_SPI_1_TRANSMIT #define DRV_SPI_RX_INT_SOURCE_IDX0 INT_SOURCE_SPI_1_RECEIVE #define DRV_SPI_ERROR_INT_SOURCE_IDX0 INT_SOURCE_SPI_1_ERROR #define DRV_SPI_QUEUE_SIZE_IDX0 10 #define DRV_SPI_RESERVED_JOB_IDX0 1 // ***************************************************************************** // ***************************************************************************** // Section: Middleware & Other Library Configuration // ***************************************************************************** // ***************************************************************************** #endif // _SYSTEM_CONFIG_H /******************************************************************************* End of File */ //以下、app.c //---------------------------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony Application Source File Company: Microchip Technology Inc. File Name: app.c Summary: This file contains the source code for the MPLAB Harmony application. Description: This file contains the source code for the MPLAB Harmony application. It implements the logic of the application's state machine and it may call API routines of other MPLAB Harmony modules in the system, such as drivers, system services, and middleware. However, it does not call any of the system interfaces (such as the "Initialize" and "Tasks" functions) of any of the modules in the system or make any assumptions about when those functions are called. That is the responsibility of the configuration-specific system files. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include "app.h" # ifndef _MY_INCLUDE_PERIPHERAL #define _MY_INCLUDE_PERIPHERAL #include <peripheral/peripheral.h> #include <peripheral/ports/plib_ports.h> #endif #include "1lcd_lib_C32.h" int delay_Clock = 200000000; //200MHz char Buf[17]; //1液晶表示バッファー char Buf2[25]; unsigned int adrStr = 0x00005678; //読み書きするSPIフラッシュの先頭アドレス char* str; char str_Hellow[] = "Hellow World"; char str_PIC32MZ[] = "PIC32MZ Run"; char str_SpiFlash[] = "SPI Flash"; void delay_us(volatile unsigned int usec) //1μsec遅延 { volatile int count; count = (int)(delay_Clock/20000000)*usec; do //実測 at 200MH (Clock=200000000) { //delay_us(1000):1000.4μsec delay_us(100):100.6μsec delay_us(10):10.5μsec delay_us(1):1.5μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void delay_ms(volatile unsigned int msec) //1msec遅延 { volatile unsigned int i; //実測:at200MH (Clock=200000000)//delay_ms(1): 1.0006msec delay_ms(100):100.04msec for(i=0; i<msec; i++) delay_us(1000); } // ***************************************************************************** // ***************************************************************************** // Section: Global Data Definitions // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* Application Data Summary: Holds application data Description: This structure holds the application's data. Remarks: This structure should be initialized by the APP_Initialize function. Application strings and buffers are be defined outside this structure. */ APP_DATA appData; // ***************************************************************************** // ***************************************************************************** // Section: Application Callback Functions // ***************************************************************************** // ***************************************************************************** /* TODO: Add any necessary callback funtions. */ // ***************************************************************************** // ***************************************************************************** // Section: Application Local Functions // ***************************************************************************** // ***************************************************************************** /* TODO: Add any necessary local functions. */ // ***************************************************************************** // ***************************************************************************** // Section: Application Initialization and State Machine Functions // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void APP_Initialize ( void ) Remarks: See prototype in app.h. */ void APP_Initialize ( void ) { /* Place the App state machine in its initial state. */ appData.state = APP_STATE_INIT; /* TODO: Initialize your application's state machine and other * parameters. */ ysSPIInitialize(); //SPI2ポート & CSポート設定 PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_G, 6 ); //RG6: out --> SCK2端子出力ポートに設定 PLIB_PORTS_PinDirectionInputSet( PORTS_ID_0, PORT_CHANNEL_G, 7 ); //RG7: out --> SDI2端子入力ポートに設定 PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_G, 8 ); //RG8: out --> SDO2端子出力ポートに設定 PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_A, 0 ); //RA0: out --> CS端子(MCP4822) //アナログ・デジタルモード設定 PLIB_PORTS_PinModeSelect(PORTS_ID_0, PORTS_ANALOG_PIN_14, PORTS_PIN_MODE_DIGITAL); //RG6/AN14ポートをデジタルモードに設定 //SCK2 PLIB_PORTS_PinModeSelect(PORTS_ID_0, PORTS_ANALOG_PIN_13, PORTS_PIN_MODE_DIGITAL); //RG7/AN13ポートをデジタルモードに設定 //SDI2 PLIB_PORTS_PinModeSelect(PORTS_ID_0, PORTS_ANALOG_PIN_12, PORTS_PIN_MODE_DIGITAL); //RG8/AN12ポートをデジタルモードに設定 //SDO2 PLIB_PORTS_PinModeSelect(PORTS_ID_0, PORTS_ANALOG_PIN_24, PORTS_PIN_MODE_DIGITAL); //RA0/AN24ポートをデジタルモードに設定 //CS /* TRISGbits.TRISG6 = 0; //RG6: out --> SCK2端子出力ポートに設定 TRISGbits.TRISG7 = 1; //RG7: out --> SDI2端子入力ポートに設定 TRISGbits.TRISG8 = 0; //RG8: out --> SDO2端子出力ポートに設定 TRISAbits.TRISA0 = 0; //RA0: out --> CS端子(MCP4822) ANSELGbits.ANSG6 = 0; //RG6 デジタルモード ANSELGbits.ANSG7 = 0; //RG7 デジタルモード ANSELGbits.ANSG8 = 0; //RG8 デジタルモード ANSELAbits.ANSA0 = 0; //RA0 デジタルモード */ //液晶ポート入出力設定----------------------------- PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_B, 15 ); PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_B, 14 ); PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_B, 13 ); PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_B, 12 ); PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_A, 10 ); PLIB_PORTS_PinDirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_A, 9 ); /* TRISBbits.TRISB15 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB14 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB13 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB12 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA10 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA9 = 0; //キャラクタ液晶ポート設定 */ lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"SPI R/W String ");// lcd_str(Buf); //液晶表示 lcd_cmd(0xC0); //2行目の先頭へ sprintf(Buf," Start !! "); // lcd_str(Buf); // 開始メッセージ1行目表示 delay_ms(2000); ysSPIInitialize();//SPIモジュール初期化 ysSST25ResetWriteProtection(); //SPIフラッシュメモリ ライトプロテクト解除 //1回目--------------------------------------------------------------------------- ysSST25SectorErase(adrStr); //セクタ消去 //ysSST25ChipErase(); //チップ消去 ysSST25WriteArray(adrStr, str_Hellow, sizeof(str_Hellow)); ////文字列書き込み delay_ms(100); lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"1st "); // lcd_str(Buf); //液晶表示 lcd_cmd(0xC0); //2行目の先頭へ str = &Buf[0]; // ポインタにアドレスを代入 ysSST25ReadArray(adrStr, str, 17) ; //文字列読出し sprintf(Buf,"%s",str); sprintf(Buf2,"Str=%s ",Buf); lcd_str(Buf2); delay_ms(3000); //2回目----------------------------------------------------------------------------- ysSST25SectorErase(adrStr); //セクタ消去 //ysSST25ChipErase(); //チップ消去 ysSST25WriteArray(adrStr, str_PIC32MZ, sizeof(str_PIC32MZ)); ////文字列書き込み delay_ms(100); lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"2nd "); // lcd_str(Buf); //液晶表示 lcd_cmd(0xC0); //2行目の先頭へ str = &Buf[0]; // ポインタにアドレスを代入 ysSST25ReadArray(adrStr, str, 17) ; //文字列読出し sprintf(Buf,"%s",str); sprintf(Buf2,"Str=%s ",Buf); lcd_str(Buf2); delay_ms(3000); //3回目------------------------------------------------------------------------ ysSST25SectorErase(adrStr); //セクタ消去 //ysSST25ChipErase(); //チップ消去 ysSST25WriteArray(adrStr, str_SpiFlash, sizeof(str_SpiFlash)); ////文字列書き込み delay_ms(100); lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"3rd "); // lcd_str(Buf); //液晶表示 lcd_cmd(0xC0); //2行目の先頭へ str = &Buf[0]; // ポインタにアドレスを代入 ysSST25ReadArray(adrStr, str, 17) ; //文字列読出し sprintf(Buf,"%s",str); sprintf(Buf2,"Str=%s ",Buf); lcd_str(Buf2); delay_ms(2000); } /****************************************************************************** Function: void APP_Tasks ( void ) Remarks: See prototype in app.h. */ void APP_Tasks ( void ) { /* Check the application's current state. */ switch ( appData.state ) { /* Application's initial state. */ case APP_STATE_INIT: { break; } /* TODO: implement your application state machine.*/ /* The default state should never be executed. */ default: { /* TODO: Handle error in application's state machine. */ break; } } } /******************************************************************************* End of File */ //以下、system_init.c //---------------------------------------------------------------------------------------------- /******************************************************************************* System Initialization File File Name: system_init.c Summary: This file contains source code necessary to initialize the system. Description: This file contains source code necessary to initialize the system. It implements the "SYS_Initialize" function, configuration bits, and allocates any necessary global system resources, such as the systemObjects structure that contains the object handles to all the MPLAB Harmony module objects in the system. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include "system_config.h" #include "app.h" #include "system_definitions.h" # ifndef _MY_INCLUDE_PERIPHERAL #define _MY_INCLUDE_PERIPHERAL #include <peripheral/peripheral.h> #include <peripheral/ports/plib_ports.h> #endif // **************************************************************************** // **************************************************************************** // Section: Configuration Bits // **************************************************************************** // **************************************************************************** //コンフィグ //----------------------------------------------------------------------- //DEVCFG0レジスタ #pragma config EJTAGBEN = NORMAL #pragma config DBGPER = ALLOW_PG2 #pragma config FSLEEP = OFF #pragma config FECCCON = OFF_UNLOCKED #pragma config BOOTISA = MIPS32 #pragma config TRCEN = OFF #pragma config ICESEL = ICS_PGx2 #pragma config JTAGEN = OFF //JTAG ポート Disable #pragma config DEBUG = OFF //---------------------------------------------------------------------- //DEVCFG1レジスタ #pragma config FNOSC = SPLL //PLL回路(システムPLL)選択 //システム発振回路 //内蔵FRC(8MHz)選択の場合:FNOSC = FRCDIV //Oscillator Selection Bits (Fast RC Osc w/Div-by-N (FRCDIV)) #pragma config FDMTEN = OFF //デッドマンタイマ OFF (Deadman Timer is disabled) //#pragma config DMTINTV = WIN_127_128 // DMT Count Window Interval (Window/Interval value is 127/128 counter value) #pragma config FSOSCEN = OFF // 副発振器OFF //Secondary Oscillator Enable (Disable SOSC) #pragma config IESO = OFF //ウェイクアップ時の2段速度スタートアップ // Internal/External Switch Over (Disabled) #pragma config POSCMOD = HS //HS: ハイスピードレゾネータモード // HS(High Speed Resonator Operation) Oscillator mode selected //EC: 外部発振器 //EC(External Clock Input Operation) mode selected // Primary Oscillator Configuration (Primary osc disabled) #pragma config OSCIOFNC = OFF //OSCCOピン出力無効 #pragma config FCKSM = CSECME //クロック発振:切替及びモニタ有効 //主発振器失陥でFRC(内蔵高速発振器)に切替 //FSCM(Fail Safe Clock Monitor)制御 #pragma config FWDTEN = OFF // ウォッチドックタイマ OFF //Watchdog Timer Disable //#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576) //#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming) //#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode) //#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%) //-------------------------------------------------------------------------------------------------------------------- // DEVCFG2レジスタ //システムクロック:200MHz //ペリフェラル周波数://default: 100MHz //PBxDIVで8系統毎に設定変更可 //PBxDIV: PERIPHERAL BUS CLOCK DIVISOR CONTROL レジスタのPBDIV<6:0>: Peripheral Bus Clock Divisor Control ビットで設定 #pragma config FPLLRNG = RANGE_13_26_MHZ //PLL Input周波数入力範囲設定// System PLL Input Range (13-26 MHz Input) //24MHz故 #pragma config FPLLIDIV = DIV_3 //PLL入力側での分周: 1/3 // PLL Input周波数 = 24MHz ÷ 3 = 8MHz // System PLL Input Divider (1x Divider) //#pragma config FPLLICLK = PLL_POSC //主発振回路選択 //内蔵FRC(8MHz)の場合はFPLLICLK = PLL_FRC// System PLL Input Clock Selection (POSC is input to the System PLL) #pragma config FPLLICLK = PLL_FRC //内蔵高速発振器選択 //★★★ バグ有 主発振回路選択の時、FPLLICLK = PLL_POSCではなくFPLLICLK = PLL_FRCを選択する。(at ver.1.33 XC32) #pragma config FPLLMULT = MUL_50 //PLL倍率:50倍 //8MHz x 50 = 400MHz //System PLL Multiplier (PLL Multiply by 50) #pragma config FPLLODIV = DIV_2 //PLL出力側での分周: 1/2 //システムクロック = 400MHz ÷ 2 = 200MHz #pragma config UPLLFSEL = FREQ_24MHZ //USBのPLL入力を 24MHz→12MHzに変換 // USB PLL Input Frequency Selection (USB PLL input is 12 MHz) #pragma config UPLLEN = ON //USBのPLL変換:イネーブル // USB PLL Enable (USB PLL is enabled) //-------------------------------------------------------------------------------------------------------------------------- //DEVCFG3レジスタ #pragma config USERID = 0xffff #pragma config FMIIEN = ON #pragma config FETHIO = ON #pragma config PGL1WAY = ON #pragma config PMDL1WAY = ON #pragma config IOL1WAY = ON #pragma config FUSBIDIO = ON /*** BF1SEQ0 ***/ #pragma config TSEQ = 0xffff #pragma config CSEQ = 0xffff // ***************************************************************************** // ***************************************************************************** // Section: Library/Stack Initialization Data // ***************************************************************************** // *****************************************************************************/ // ***************************************************************************** // ***************************************************************************** // Section: Driver Initialization Data // ***************************************************************************** // ***************************************************************************** /*** TMR Driver Initialization Data ***/ const DRV_TMR_INIT drvTmr0InitData = { .moduleInit.sys.powerState = DRV_TMR_POWER_STATE_IDX0, .tmrId = DRV_TMR_PERIPHERAL_ID_IDX0, .clockSource = DRV_TMR_CLOCK_SOURCE_IDX0, .prescale = DRV_TMR_PRESCALE_IDX0, .mode = DRV_TMR_OPERATION_MODE_IDX0, .interruptSource = DRV_TMR_INTERRUPT_SOURCE_IDX0, .asyncWriteEnable = false, }; /*** SPI Driver Initialization Data ***/ /*** Index 0 ***/ DRV_SPI_INIT drvSpi0InitData = //SPI通信諸元 初期化 { .spiId = DRV_SPI_SPI_ID_IDX0, .taskMode = DRV_SPI_TASK_MODE_IDX0, .spiMode = DRV_SPI_SPI_MODE_IDX0, .allowIdleRun = DRV_SPI_ALLOW_IDLE_RUN_IDX0, .spiProtocolType = DRV_SPI_SPI_PROTOCOL_TYPE_IDX0, .commWidth = DRV_SPI_COMM_WIDTH_IDX0, .spiClk = DRV_SPI_SPI_CLOCK_IDX0, .baudRate = DRV_SPI_BAUD_RATE_IDX0, .bufferType = DRV_SPI_BUFFER_TYPE_IDX0, .clockMode = DRV_SPI_CLOCK_MODE_IDX0, .inputSamplePhase = DRV_SPI_INPUT_PHASE_IDX0, .queueSize = DRV_SPI_QUEUE_SIZE_IDX0, .jobQueueReserveSize = DRV_SPI_RESERVED_JOB_IDX0, }; // ***************************************************************************** // ***************************************************************************** // Section: System Data // ***************************************************************************** // ***************************************************************************** /* Structure to hold the object handles for the modules in the system. */ SYSTEM_OBJECTS sysObj; // ***************************************************************************** // ***************************************************************************** // Section: Module Initialization Data // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* System Clock Initialization Data */ const SYS_CLK_INIT sysClkInit = { .moduleInit = {0}, .systemClockSource = SYS_CLK_SOURCE, .systemClockFrequencyHz = SYS_CLK_FREQ, .waitTillComplete = true, .secondaryOscKeepEnabled = true, .onWaitInstruction = SYS_CLK_ON_WAIT, }; /*** System Device Control Initialization Data ***/ const SYS_DEVCON_INIT sysDevconInit = { .moduleInit = {0}, }; // ***************************************************************************** // ***************************************************************************** // Section: Static Initialization Functions // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** // Section: System Initialization // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void SYS_Initialize ( SYS_INIT_DATA *data ) Summary: Initializes the board, services, drivers, application and other modules. Remarks: See prototype in system/common/sys_module.h. */ void SYS_Initialize ( void* data ) { /* Core Processor Initialization */ SYS_CLK_Initialize(&sysClkInit); sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit); SYS_DEVCON_PerformanceConfig(SYS_DEVCON_SYSTEM_CLOCK); /* System Services Initialization */ SYS_INT_Initialize(); /* Initialize Drivers */ sysObj.drvTmr0 = DRV_TMR_Initialize(DRV_TMR_INDEX_0, (SYS_MODULE_INIT *)&drvTmr0InitData); SYS_INT_VectorPrioritySet(INT_VECTOR_T1, INT_PRIORITY_LEVEL1); SYS_INT_VectorSubprioritySet(INT_VECTOR_T1, INT_SUBPRIORITY_LEVEL0); /*** SPI Driver Index 0 initialization***/ //SPI2用 ピン割り付け(リマップ) RPG8Rbits.RPG8R = 0b0110; //RG8ピンに SDO2の出力を割り付け SDI2Rbits.SDI2R = 0b0001; //RPG7ピンに SDI2(入力)を割り付け sysObj.spiObjectIdx0 = DRV_SPI_Initialize(0, (const SYS_MODULE_INIT * const)&drvSpi0InitData); /* Initialize System Services */ /* Initialize Middleware */ /* Enable Global Interrupts */ SYS_INT_Enable(); /* Initialize the Application */ APP_Initialize(); } /******************************************************************************* End of File */ //以下、spiMem_25LC_lib.h //------------------------------------------------------------------------------------------------------------ //spiMem_25LC_lib.h ///////////////////////////////////////////////////////////////////////////////////////////////////////// // SPIフラッシュメモリ 読み書きライブラリ // 関数 // void ysSPIInitialize(void) …… 初期化 // // unsigned char ysSST25ReadByte(unsigned int address) …… 1バイト読み込み // 引数:読み込むメモリのアドレス、戻り値:読み込み値 // void ysSST25WriteByte(unsigned char data, unsigned int address) ……1バイト書込み // 第1引数:書込み値、第2引数:書き込むメモリのアドレス // void ysSST25ReadArray(unsigned int address, unsigned char *pData, unsigned short int nCount)……文字列読み込み // 第1引数:読み込む先頭アドレス、第2引数:読み込んだ文字列のポインタ、第3引数:読込む文字列の長さ // void ysSST25WriteArray(unsigned int address, unsigned char *pData, unsigned short nCount) ……文字列書込み // 第1引数:書き込む先頭アドレス、第2引数:書き込む文字列のポインタ、書き込む文字列の長さ // ////////////////////////////////////////////////////////////////////////////////////////////////////////// //適用SPIメモリ //マイクロチップ、テキサス他 //25LXXX 例:25L640(64Kビット) //25LCXXX 例:25LC128(128Kビット) //25AAXXX 例:25AA512(512Kビット) //SST25VFXXX 例:SST25VF16B(16Mビット) //LC25 コマンド #define ysSST25_CMD_READ (unsigned)0x03 //Read instruction, 03H, #define ysSST25_CMD_WRITE (unsigned)0x02 //Page-Program instruction, 02H //To program up to 256 Bytes #define ysSST25_CMD_WREN (unsigned)0x06 //Write-Enable (WREN) instruction, 06H, #define ysSST25_CMD_RDSR (unsigned)0x05 //Read-Status-Register (RDSR) instruction,05H, #define ysSST25_CMD_EWSR (unsigned)0x50 //64 KByte Block-Erase #define ysSST25_CMD_SER (unsigned)0x20 //4 KByte Sector-Erase #define ysSST25_CMD_ERASE (unsigned)0x60 //Chip-Erase #define ysSST25_CMD_WRSR (unsigned)0x01 // Write Status Register //SPIモジュールチャンネル設定 #define SPIXCON SPI2CON //SPI2コントロールレジスタ設定 #define SPIXSTAT SPI2STAT //SPI2ステータスレジスタ設定 #define SPIXCONbits SPI2CONbits #define SPIXSTATbits SPI2STATbits #define SPIXBUF SPI2BUF //SPI2バッファレジスタ設定 #define SPIXBRG SPI2BRG //SPI2ボーレートレジスタ設定 //CS ポート設定 #define ysSST25CSLow() LATAbits.LATA0 = 0 #define ysSST25CSHigh() LATAbits.LATA0 = 1 //プロトタイプ宣言 void ysSPIInitialize(void); void ysSPIPut(unsigned char data); unsigned char ysSPIGet (void); unsigned char ysSST25IsWriteBusy(void); void ysSST25WriteEnable(void); void ysSST25SectorErase(unsigned int address); void ysSST25ChipErase(void); void ysSST25ResetWriteProtection(void); unsigned char ysSST25ReadByte(unsigned int address); void ysSST25WriteByte(unsigned char data, unsigned int address); void ysSST25ReadArray(unsigned int address, unsigned char *pData, unsigned short int nCount); void ysSST25WriteArray(unsigned int address, unsigned char *pData, unsigned short nCount); //参考 //SPIフラッシュメモリ 諸元 //16 Mbit SPI Serial Flash SST25VF016B //Features //Single Voltage Read and Write Operations 2.7-3.6V //Serial Interface Architecture SPI Compatible: Mode 0 and Mode 3 //High Speed Clock Frequency? Up to 80 MHz //Superior Reliability Endurance: 100,000 Cycles (typical) // Greater than 100 years Data Retention //Low Power Consumption: Active Read Current: 10 mA (typical) // Standby Current: 5 μA (typical) //Flexible Erase Capability Uniform 4 KByte sectors // Uniform 32 KByte overlay blocks // Uniform 64 KByte overlay blocks //Fast Erase and Byte-Program: Chip-Erase Time: 35 ms (typical) // Sector-/Block-Erase Time: 18 ms (typical) // Byte-Program Time: 7 μs (typical) //以下、spiMem_25LC_lib.c //--------------------------------------------------------------------------------------------------- //spiMem_25LC_lib.c #include "spiMem_25LC_lib.h" # ifndef _MY_INCLUDE_PERIPHERAL #define _MY_INCLUDE_PERIPHERAL #include <peripheral/peripheral.h> #include <peripheral/ports/plib_ports.h> #endif void ysSPIInitialize(void) { //チャンネル諸元設定 SPIXCON = 0; //SPIX 無効 SPIXSTAT = 0; SPIXCONbits.FRMEN = 0; //フレーム化 ディセーブル SPIXCONbits.MSTEN = 1; //マスターモード イネーブル SPIXCONbits.CKP = 0; //クロックの極性: アイドル時 = Low、 アクティブ = High SPIXCONbits.CKE = 1; //クロックエッジ制御: イネーブル// クロックがActive→idleに変化した時データ変化 //Clock Edge control //MCP4822: クロックの立上りエッジでデータ読み込み SPIXCONbits.SMP = 1; //データ抽出タイミング: データの後縁 //Sample phase control SPIXCONbits.MODE32 = 0; //データ幅: 8ビット SPIXCONbits.MODE16 = 0; SPIXBRG = 49; //SPIクロック周波数[Hz} = Fpbclk2(ペリフェラルバスクロック)/ 2 x (SPI2BRG + 1) // = 100MHz /2 /(49 +1) = 1 MHz SPIXCONbits.ON = 1; //SPI2 有効 } void ysSPIPut(unsigned char data) { while(!SPIXSTATbits.SPITBE); //送信バッファーが空になるまで待つ SPIXBUF = data; //送受信バッファにデータを書き込む while(!SPIXSTATbits.SPIRBF); //RX FIFOが空になるまでするまで待つ return; } unsigned char ysSPIGet (void) { unsigned char spiData = 0; spiData = SPIXBUF; //送受信バッファのデータを読込む return spiData; } unsigned char ysSST25IsWriteBusy(void) { unsigned char temp; ysSPIInitialize(); //SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_RDSR); ysSPIGet(); ysSPIPut(0); //ダミーを送信 temp = ysSPIGet(); ysSST25CSHigh(); return (temp & 0x01); } void ysSST25WriteEnable(void) { ysSPIInitialize(); //SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_WREN); ysSPIGet(); ysSST25CSHigh(); } void ysSST25SectorErase(unsigned int address) //セクタ消去 //消去セクタ--> FFH //消去するセクタは 最初に送信されるMSBにより決まる { ysSST25WriteEnable(); ysSPIInitialize(); //SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_SER); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x00FF0000) >> 16)); //書込みアドレスの第2バイト(MSB)送信 //SPIPut(((DWORD_VAL) address).v[2]); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x0000FF00) >> 8 )); //書込みアドレスの第1バイト送信 //SPIPut(((DWORD_VAL) address).v[1]) ysSPIGet(); ysSPIPut((unsigned char)(address & 0x000000FF)); //書込みアドレスの第0バイト(LSB)送信 //SPIPut(((DWORD_VAL) address).v[0]); ysSPIGet(); ysSST25CSHigh(); // Wait for write end while(ysSST25IsWriteBusy()); } void ysSST25ChipErase(void) //全チップ消去 //全データ --> FFH { ysSST25WriteEnable(); //追加 ysSST25CSLow(); ysSPIInitialize();//SPIモジュール初期化 ysSPIPut(ysSST25_CMD_ERASE); ysSPIGet(); ysSST25CSHigh(); while(ysSST25IsWriteBusy()); } void ysSST25ResetWriteProtection(void) //ライトプロテクトリセット { ysSPIInitialize(); //SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_EWSR); //書込みイネーブル // send write enable command //The Enable-Write-Status-Register (EWSR) instruction arms the Write-Status-Register (WRSR)instruction and opens the status register for alteration. ysSPIGet(); ysSST25CSHigh(); ysSST25CSLow(); ysSPIPut(ysSST25_CMD_WRSR); //ステータスレジスタ(WRSR)書換えコマンド送信 //The Write-Status-Register instruction writes new values to the BP3, BP2, BP1, BP0, and BPL bits of the status register. ysSPIGet(); ysSPIPut(0); //ステータスレジスタ クリア --> BP3, BP2, BP1, BP0 = 0 --> ライトプロテクト解除 ysSPIGet(); ysSST25CSHigh(); while(ysSST25IsWriteBusy()); // Wait for write end } unsigned char ysSST25ReadByte(unsigned int address) //1バイト読み込み { unsigned char temp; ysSPIInitialize(); //SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_READ); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x00FF0000) >> 16)); //書込みアドレスの第2バイト(MSB)送信 //SPIPut(((DWORD_VAL) address).v[2]); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x0000FF00) >> 8 )); //書込みアドレスの第1バイト送信 //SPIPut(((DWORD_VAL) address).v[1]) ysSPIGet(); ysSPIPut((unsigned char)(address & 0x000000FF)); //書込みアドレスの第0バイト(LSB)送信 //SPIPut(((DWORD_VAL) address).v[0]); ysSPIGet(); ysSPIPut(0); //ダミーを送信 temp = ysSPIGet(); ysSST25CSHigh(); return (temp); } void ysSST25WriteByte(unsigned char data, unsigned int address) //1バイト書込み { ysSST25WriteEnable(); ysSPIInitialize(); //SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_WRITE); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x00FF0000) >> 16)); //書込みアドレスの第2バイト(MSB)送信 //SPIPut(((DWORD_VAL) address).v[2]); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x0000FF00) >> 8 )); //書込みアドレスの第1バイト送信 //SPIPut(((DWORD_VAL) address).v[1]) ysSPIGet(); ysSPIPut((unsigned char)(address & 0x000000FF)); //書込みアドレスの第0バイト(LSB)送信 //SPIPut(((DWORD_VAL) address).v[0]); ysSPIGet(); ysSPIPut(data); //データ(unsigned char)を送信 ysSPIGet(); ysSST25CSHigh(); // Wait for write end while(ysSST25IsWriteBusy()); } void ysSST25WriteArray(unsigned int address, unsigned char *pData, unsigned short nCount) //文字列書込み { unsigned int addr; unsigned char *pD; unsigned short counter; addr = address; pD = pData; // WRITE for(counter = 0; counter < nCount; counter++) { ysSST25WriteByte(*pD++, addr++); } } void ysSST25ReadArray(unsigned int address, unsigned char *pData, unsigned short int nCount) //文字列読み込み { ysSPIInitialize();//SPIモジュール初期化 ysSST25CSLow(); ysSPIPut(ysSST25_CMD_READ); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x00FF0000) >> 16)); //書込みアドレスの第2バイト(MSB)送信 //SPIPut(((DWORD_VAL) address).v[2]); ysSPIGet(); ysSPIPut((unsigned char)((address & 0x0000FF00) >> 8 )); //書込みアドレスの第1バイト送信 //SPIPut(((DWORD_VAL) address).v[1]) ysSPIGet(); ysSPIPut((unsigned char)(address & 0x000000FF)); //書込みアドレスの第0バイト(LSB)送信 //SPIPut(((DWORD_VAL) address).v[0]); ysSPIGet(); while(nCount--) { ysSPIPut(0); *pData++ = ysSPIGet(); } ysSST25CSHigh(); } //以下、1lcd_lib_C32.h //------------------------------------------------------------------------------------------------ //************************************************************************* //インクルードファイル 1lcd_lib_C32.h //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************* #include <p32xxxx.h> #define lcd_Clock 200000000 // 単位はHzで指定 // LCDポート設定 #define lcd_port_DB7 LATBbits.LATB15 //LCDのDB7(14番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB6 LATBbits.LATB14 //LCDのDB6(13番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB5 LATBbits.LATB13 //のDB5(12番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB4 LATBbits.LATB12 //LCDのDB4(11番ピン)に接続されつPIC側ポート番号設定 #define lcd_rs LATAbits.LATA9 //LCDのrs(4番ピン)に接続されるPIC側ポート番号設定 #define lcd_stb LATAbits.LATA10 //LCDのstb(6番ピン)に接続されるPIC側ポート番号設定 void lcd_out(char code, char flag); void lcd_data(char asci); void lcd_cmd(char cmd); void lcd_clear(void); void lcd_init(void); void lcd_str(char *str); //以下、1lcd_lib_C32.c //------------------------------------------------------------------------------------------------------- //************************************************************************** //インクルードファイル 1lcd_lib_C32.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C32コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C32.h" void lcd_delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(lcd_Clock/20000000)*usec; do //実測: at 200MH (Clock=200000000) { //delay_us(1000)→1000.4μsec、 delay_us(100)→100.6μsec、delay_us(10)→10.5μsec、delay_us(1)→1.5μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void lcd_delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) lcd_delay_us(1000); } //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 lcd_delay_us(3); //1μsecウェイト // lcd_delay_us(1); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) lcd_delay_us(3); //1μsecウェイト // lcd_delay_us(1); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 lcd_delay_us(50); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 lcd_delay_ms(2); // 2msec待ち else lcd_delay_us(50); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { lcd_delay_ms(20); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(5); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set lcd_delay_ms(1); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home }
<動作結果>
表示内容 | 液晶表示 | 備考 | |
@ | 最初の読み書き後の表示 | ||
A | 2番目の読み書き後の表示 | ||
B | 3番目の読み書き後の表示 |
★ SDカード読み書き(EOF) <dsPIC C30編>
書き込んだデータをすぺて読み出す例を以下に紹介します。FSfread( )の戻り値は読み込んだブロック数です。以下の例
では読み込もうとした時0が戻ってきたら(エラーの場合もありますが)ファイルエンド(End OF File)と判断しています。
<試作品の仕様>
・500msecごとにSDカードに整数を書き込む
・500msec毎の読み出しをおこない、SDカードのデータをすべて読み出す
・読み出したデータを読み出した順番に液晶1行目の左から順番に表示する。5つめから8つめまでのデータは2行目の
左から順番にならべる。
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> ///**************************************************************************************************/ // SDカード書き込み 及び 読み出し File Name: SD R_W Basic3 4013.c // EOF // dsPIC30F4013 //****************************************************************************************************/ // MPLAB プロジェクトへの追加ファイル // Source Filesフォルダ FSIO.c // SD-SPI.c // 1lcd_lib_C30.c // SD R_W Basic3 4013.c // Header Filesフォルダ FScohfig.h // FSDefs.h // FSIO.h // GenericTypeDefs.h // SD-SPI.h // 1lcd_lib_C30.h // Linker Scriptフォルダ p30f2012.gld // Library Filesフォルダ lib30F2012-coff.a #include "p30f4013.h" #include "1lcd_lib_C30.h" #include <stdio.h> #include <timer.h> #include "FSIO.h" _FOSC(CSW_FSCM_OFF & XT_PLL8); // 10MHzx8=80MHz _FWDT(WDT_OFF); _FBORPOR(PBOR_ON & BORV_20 //2V:BORV_20 2.7V:BORV_27 4.2V:BORV_42 4.5V:BORV_45 & PWRT_64 & MCLR_EN); _FGS(CODE_PROT_OFF); char Buf[17]; //文字列のバッファー用レジスタ unsigned int Buf_Input[1]; //AD読込みのホールド値&SDカード書き込み値 unsigned int Buf_Output[1]; //SDカード読込み値 unsigned int SD[20]; char blk = ' '; //ブランク int N_Write; //書き込み回数戻り値 unsigned int N_Read; //読み出し回数戻り値 FSFILE* pfile; //SDカードのファイルポインタ unsigned int ix = 0,iy = 0; int Mode_SD = 0; // ///プロトタイプ関数 void delay_ms(unsigned int); //------------------------------------------------------- void delay_ms(unsigned int N) //ウェイト関数 { __delay32(Clock/4000*N); } void _ISR _T1Interrupt(void) //500msec毎の割込み発生 { IFS0bits.T1IF = 0; //IFS0レジスタの T1IF(タイマ1の割込み検出)フラグリセット if(Mode_SD == 0) //SDカードへ書き込みの場合 { Buf_Input[0] = 100 * (ix +1); //書き込みデータをセット N_Write = FSfwrite((const void*)Buf_Input,sizeof(unsigned int),1,pfile);//ファイルにデータ書き込み if(N_Write == 1) //正常な場合:書き込み回数が返ってくる { lcd_clear(); sprintf(Buf,"Write No%d OK !!",ix); //液晶に"Write OK !" を表示 lcd_str(Buf); delay_ms(100); } else //異常な場合 { lcd_clear(); sprintf(Buf,"Write No%d NG !!",ix); //液晶に"Write NG !" を表示 lcd_str(Buf); return 0; } ix++; } else //SDカードから読み込みの場合 { N_Read = FSfread(Buf_Output,sizeof(unsigned int),1,pfile);//ファイルからデータ読込み if(N_Read != 0) { SD[iy] = Buf_Output[0]; iy++; } } } /// メイン関数 int main(void) { int i; //// ポート入出力モード設定 TRISB = 0b0000000000000000; // in : TRISC = 0b0100000000000000; // in : RC14(Hold SW) TRISD = 0b0000000000000011; // in : RD0(CD) RD1(WE) TRISF = 0b0000000000000100; // in : RF2(SDI) /// タイマ1周期 10msec /// bit15:タイマOn制御ビット bit14:未実装 ビット13 OpenTimer1(T1_ON & //タイマ1ON T1_GATE_OFF & //ゲート制御off T1_PS_1_256 & //プリスケーラ 1/256 T1_SYNC_EXT_OFF & //クロック同期制御OFF T1_SOURCE_INT , //クロック源:内部クロック 80000000/4/2/256 - 1 //2Hz → 500msec毎の割込み ); lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); // 全消去 sprintf(Buf,"SD R/W INT !!%c",blk);//arguementがないと遅い C30のバグ? lcd_str(Buf); //液晶表示 delay_ms(1000); for(i = 0; i < 20; i++)SD[i] = 0; //SD[i]の値:0リセット PORTFbits.RF5 = 0; //CS=0 SDカードのチップセレクトenable LATDbits.LATD2 = 1; while(!FSInit()); //SDカードイニシャライズ SDカードの実装とフォーマット済をチェック pfile = FSfopen("DATA.DAT","w"); //ファイル書き込みモードでオープン 但しファイルがなければ新規ファイル作成 Mode_SD = 0; ix = 0; ConfigIntTimer1(T1_INT_PRIOR_7 & T1_INT_ON); //割込みレベル5 タイマ1割込みON EnableIntT1; //割込み許可 do { }while(ix < 6); // 6個の符号なし整数(2バイト)データをSDカードに書き込むまで繰り返す DisableIntT1; FSfclose(pfile); // ファイルを閉じる pfile = FSfopen("DATA.DAT","r"); //ファイル読込みモードでオープン Mode_SD = 1; iy = 0; N_Read = 1; //0だとwhile(N_Read !=0)が割込みが入る前に真となりループを抜けてしまう EnableIntT1; //タイマ1割込み許可 do { }while(N_Read !=0); //N_ReaDに0が戻ってくる(EOF)まで待つ FSfclose(pfile); // ファイルを閉じる DisableIntT1; PORTFbits.RF5 = 1; // CS = 1 lcd_clear(); sprintf(Buf,"%u %u %u %u ",SD[0],SD[1],SD[2],SD[3]);//SDカードから読み込んだデータを液晶に表示 lcd_str(Buf); lcd_cmd(0xC0);//2行目の先頭へ sprintf(Buf,"%u %u %u %u ",SD[4],SD[5],SD[6],SD[7]);//SDカードから読み込んだデータを液晶に表示 lcd_str(Buf); while(1); return 0; }
//************************************************************************** //インクルードファイル 1lcd_lib_C30.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C30コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C30コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C30.h" unsigned int _1usec; // 1μsec待つに必要なウェイト回数 unsigned int _50usec; //50μsec待つに必要なウェイト回数 unsigned long N_msec; // 1msec待つに必要なウェイト回数 //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 __delay32(_1usec); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) __delay32(_1usec); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 __delay32(_50usec); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 __delay32(2*N_msec); // 2msec待ち else __delay32(_50usec); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 // __delay32(15*N_msec); //15msecウェイト } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { _1usec =(unsigned int)( Clock / 4000000); // 1μsecに要するウェイト回数 //__delay32(N) : Nが11以下の場合でも11回ウェイト _50usec = (unsigned int)(Clock / 4000000 * 50); //50μescに要するウェイト回数 N_msec = (unsigned long int)(Clock / 4000); // 1msecに要するウェイト回数 // = Clock / 4000000*1000 __delay32(20*N_msec); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set __delay32(5*N_msec); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set __delay32(N_msec); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set __delay32(N_msec); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set __delay32(N_msec); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home } ************************************************************************************************* ************************************************************************************************* *** *** *** その他のインクルードファイルは *** *** 「C言語ではじめるPIC24F活用ガイドブック」(後閑哲也 著 技術評論社) *** *** の付属CDに収納されています。 *** ************************************************************************************************* ************************************************************************************************* //************************************************************************************************ //************************************************************************************************ //以下は インクルードファイル SD-SPI.hの中で変更部位のみを抜粋したものです。 ピンアサイン関係の 変更です。 // … … /********************************************************************/ /* Pin and register definitions */ /********************************************************************/ #define SD_CS PORTFbits.RF5 #define SD_CS_TRIS TRISFbits.TRISF5 #define SD_CD PORTDbits.RD0 #define SD_CD_TRIS TRISDbits.TRISD0 #define SD_WE PORTDbits.RD1 #define SD_WE_TRIS TRISDbits.TRISD1 // Registers for the SPI module you want to use #define SPICON1 SPI1CON #define SPISTAT SPI1STAT #define SPIBUF SPI1BUF #define SPISTAT_RBF SPI1STATbits.SPIRBF #define SPICON1bits SPI1CONbits #define SPISTATbits SPI1STATbits // Tris pins for SCK/SDI/SDO lines #define SPICLOCK TRISFbits.TRISF6 #define SPIIN TRISFbits.TRISF2 #define SPIOUT TRISFbits.TRISF3 … … //************************************************************************************************ //************************************************************************************************ // 以下は インクルードファイル SD-SPI.cの中で修正した部分のみを抜粋したものです。 // SDカードのソケットにより書き込みプロテクトの論理が異なるものがあるようです。 // (後閑さんにおしえていただきました)
// わたしが使用したSDカードソケットはサンハヤト鰍フCK29です。CK29のライトプロテクトWEの論理は // ”ライトプロテクトが書き込み可能な位置にあるSDカードを奥まで挿入すると ON ”です。すなわち // 以下の場合 SDカードのWEはOFFです。 // ・SDカードが挿入されていない場合 // ・ライトプロテクトが書き込み不可の位置にあるSDカードが奥まで挿入されている場合
//
// 以下は修正前のソースコードです。SDカードの検出チェックの部分です。修正したものは SD_WEの // 前の”!”が削除されています。 // // BYTE // WriteProtectState(void)
// {
// return(!SD_WE); // 修正後は”!”が削除されています。
// }
// // // // 以下は修正後のソースコードです。 BYTE WriteProtectState(void)
{
return(SD_WE); // ”!”が削除されています。
}
// 以下はFSconfig.hファイルの中で変更した部分のみを記載しています。システムクロックを20MHzから80MHzに変更
//したことに伴う変更です
// Define the system clock speed
//#define SYSTEM_CLOCK (DWORD)20000000
#define SYSTEM_CLOCK (DWORD)80000000
<動作結果>
6個のデータを書き込んだあと、FSfread( ) で6個のデータすべてを読み出した結果を下記に示します。
★ SDカード読み書き(EOF) <PIC32MX編>
<試作品の仕様>
・500msecごとにSDカードに整数を書き込む
・500msec毎の読み出しをおこない、SDカードのデータをすべて読み出す
・読み出したデータを読み出した順番に液晶1行目の左から順番に表示する。5つめから8つめまでのデータは2行目の
左から順番にならべる。
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例>
// SDカード読書き EOF // PIC32MX460F512L #include <proc/p32mx460f512l.h> //PIC32MX460F512L #include <plib.h> // PIC32 peripheral library //for SYSTEMConfigPerformance() #include "1lcd_lib_C32.h" #include "FSIO.h" // コンフィギュレーション設定 // CPU=80MHz Peri=80MHz,HS+PLL,Divider=1/2,PLL=x20,WDT=Off #pragma config FNOSC=PRIPLL, POSCMOD=HS, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_1 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 char Buf[17]; //文字列のバッファー用レジスタ unsigned int Buf_Input[1]; //AD読込みのホールド値&SDカード書き込み値 unsigned int Buf_Output[1]; //SDカード読込み値 unsigned int SD[20]; int N_Write; //書き込み回数戻り値 FSFILE* pfile; //SDカードのファイルポインタ unsigned int N_Read; //読み出し回数戻り値 unsigned int ix = 0,iy = 0; int Mode_SD = 0; // void delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do //実測: at Clock=80000000 { //delay_us(1000)→1003μsec、 delay_us(100)→102μsec、delay_us(10)→11μsec、delay_us(1)→1.6μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) delay_us(1000); } void __ISR(20,ipl2)T45Hander(void) //タイマ4+5 32bitタイマ割り込み 500msec毎 { mT5ClearIntFlag(); //フラグクリア if(Mode_SD == 0) //SDカードへ書き込みの場合 { Buf_Input[0] = 100 * (ix +1); //書き込みデータをセット N_Write = FSfwrite((const void*)Buf_Input,sizeof(unsigned int),1,pfile);//ファイルにデータ書き込み if(N_Write == 1) //正常な場合:書き込み回数が返ってくる { lcd_clear(); sprintf(Buf,"Write No%d OK !!",ix); //液晶に"Write OK !" を表示 lcd_str(Buf); delay_ms(100); } else //異常な場合 { lcd_clear(); sprintf(Buf,"Write No%d NG !!",ix); //液晶に"Write NG !" を表示 lcd_str(Buf); return 0; } ix++; } else //SDカードから読み込みの場合 { N_Read = FSfread(Buf_Output,sizeof(unsigned int),1,pfile);//ファイルからデータ読込み if(N_Read != 0) { SD[iy] = Buf_Output[0]; iy++; } } } int main(void) { int i; SYSTEMConfigPerformance(80000000); // システム最適化 TRISC = 0; //Cポートを出力モードに設定 TRISE = 0; //Eポートを出力モードに設定 DDPCONbits.JTAGEN = 0;// lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); // 全消去 sprintf(Buf,"SD EOF !!");// lcd_str(Buf); //液晶表示 delay_ms(1000); OpenTimer45(T45_ON | // タイマ1 イネーブル //T1_OFF → タイマ1 ディセーブル T45_SOURCE_INT | //クロックソース:インターナル //T1_SOURCE_EXT → 外部発振器 T45_PS_1_256, //プリスケール 1/256 //1/1、1/2、1/4、1/8、1/16、1/32、1/64、1/256 156246 //PRx値: T0[msec] = 1000/80000000*256*156246 = 499.987 msec //PICMX32は1クロックで1命令 //周期 T0[sec] = 1/Fosc × プリスケーラの逆数 × PRx値 ); for(i = 0; i < 20; i++)SD[i] = 0; //SD[i]の値:0リセット LATCbits.LATC3 = 0; //CS=0 SDカードのチップセレクトenable while(!FSInit()); //SDカードイニシャライズ SDカードの実装とフォーマット済をチェック pfile = FSfopen("DATA.DAT","w"); //ファイル書き込みモードでオープン 但しファイルがなければ新規ファイル作成 Mode_SD = 0; ix = 0; ConfigIntTimer45(T45_INT_ON | T45_INT_PRIOR_2); //タイマ1割込ON、割り込みレベル2 INTEnableSystemMultiVectoredInt(); //割り込みをマルチベクタモードで許可 do { }while(ix < 6); // 6個の符号なし整数(2バイト)データをSDカードに書き込むまで繰り返す DisableIntT45; //タイマ45割込み禁止 FSfclose(pfile); // ファイルを閉じる pfile = FSfopen("DATA.DAT","r"); //ファイル読込みモードでオープン Mode_SD = 1; iy = 0; N_Read = 1; //0だとwhile(N_Read !=0)が割込みが入る前に真となりループを抜けてしまう EnableIntT45; //タイマ45割込み許可 do { }while(N_Read !=0); //N_ReaDに0が戻ってくる(EOF)まで待つ FSfclose(pfile); // ファイルを閉じる DisableIntT45; LATCbits.LATC3 = 1; //CS=1 SDカードのチップセレクトdisable lcd_clear(); sprintf(Buf,"%u %u %u %u ",SD[0],SD[1],SD[2],SD[3]);//SDカードから読み込んだデータを液晶に表示 lcd_str(Buf); lcd_cmd(0xC0);//2行目の先頭へ sprintf(Buf,"%u %u %u %u ",SD[4],SD[5],SD[6],SD[7]);//SDカードから読み込んだデータを液晶に表示 lcd_str(Buf); while(1); return 0; } //************************************************************************* //インクルードファイル 1lcd_lib_C32.h //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************* #include <proc/p32mx460f512l.h> //PIC32MX460F512L #define Clock 80000000 // 単位はHzで指定 // LCDポート設定 #define lcd_port_DB7 LATEbits.LATE7 //LCDのDB7(14番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB6 LATEbits.LATE6 //LCDのDB6(13番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB5 LATEbits.LATE5 //LCDのDB5(12番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB4 LATEbits.LATE4 //LCDのDB4(11番ピン)に接続されつPIC側ポート番号設定 #define lcd_stb LATEbits.LATE3 //LCDのstb(6番ピン)に接続されるPIC側ポート番号設定 #define lcd_rs LATEbits.LATE2 //LCDのrs(4番ピン)に接続されるPIC側ポート番号設定 void lcd_out(char code, char flag); void lcd_data(char asci); void lcd_cmd(char cmd); void lcd_clear(void); void lcd_init(void); void lcd_str(char *str); //************************************************************************** //インクルードファイル 1lcd_lib_C32.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C32コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C32.h" void lcd_delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void lcd_delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) lcd_delay_us(1000); } //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 lcd_delay_us(1); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) lcd_delay_us(1); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 lcd_delay_us(50); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 lcd_delay_ms(2); // 2msec待ち else lcd_delay_us(50); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { lcd_delay_ms(20); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(5); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set lcd_delay_ms(1); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home } //HardwareProfile.h にピンアサイン変更の修正をおこないます。 /****************************************************************************** * * Microchip Memory Disk Drive File System * ****************************************************************************** * FileName: HardwareProfile.h * Dependencies: None * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32 * Compiler: C18/C30/C32 * Company: Microchip Technology, Inc. * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the 鼎ompany・ for its PICmicroョ Microcontroller is intended and * supplied to you, the Company痴 customer, for use solely and * exclusively on Microchip PICmicro Microcontroller products. The * software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN 鄭S IS・CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * *****************************************************************************/ #ifndef _HARDWAREPROFILE_H_ #define _HARDWAREPROFILE_H_ // Define your clock speed here // Sample clock speed for PIC18 #if defined (__18CXX) #define GetSystemClock() 40000000 // System clock frequency (Hz) #define GetPeripheralClock() GetSystemClock() // Peripheral clock freq. #define GetInstructionClock() (GetSystemClock() / 4) // Instruction clock freq. // Sample clock speed for a 16-bit processor #elif defined (__C30__) #define GetSystemClock() 32000000 #define GetPeripheralClock() GetSystemClock() #define GetInstructionClock() (GetSystemClock() / 2) // Clock values #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer #define TIMER_PERIOD 20000 // Definition for use with a tick timer // Sample clock speed for a 32-bit processor #elif defined (__PIC32MX__) // Indicates that the PIC32 clock is running at 48 MHz //#define RUN_AT_48MHZ // Indicates that the PIC32 clock is running at 24 MHz //#define RUN_AT_24MHZ // Indicates that the PIC32 clock is running at 80 MHz #define RUN_AT_80MHZ // Various clock values #if defined(RUN_AT_48MHZ) #define GetSystemClock() 48000000UL // System clock frequency (Hz) #define GetPeripheralClock() 48000000UL // Peripheral clock frequency #define GetInstructionClock() (GetSystemClock()) // Instruction clock frequency #elif defined(RUN_AT_24MHZ) #define GetSystemClock() 24000000UL #define GetPeripheralClock() 24000000UL #define GetInstructionClock() (GetSystemClock()) #elif defined(RUN_AT_80MHZ) #define GetSystemClock() (80000000ul) #define GetPeripheralClock() (GetSystemClock()/2) #define GetInstructionClock() (GetSystemClock()) #else #error Choose a speed #endif // Clock values #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer #define TIMER_PERIOD 37500 // Definition for use with a tick timer #endif // Select your interface type // This library currently only supports a single physical interface layer at a time // Description: Macro used to enable the SD-SPI physical layer (SD-SPI.c and .h) #define USE_SD_INTERFACE_WITH_SPI // Description: Macro used to enable the CF-PMP physical layer (CF-PMP.c and .h) //#define USE_CF_INTERFACE_WITH_PMP // Description: Macro used to enable the CF-Manual physical layer (CF-Bit transaction.c and .h) //#define USE_MANUAL_CF_INTERFACE // Description: Macro used to enable the USB Host physical layer (USB host MSD library) //#define USE_USB_INTERFACE /*********************************************************************/ /******************* Pin and Register Definitions ********************/ /*********************************************************************/ /* SD Card definitions: Change these to fit your application when using an SD-card-based physical layer */ #ifdef USE_SD_INTERFACE_WITH_SPI #ifdef __18CXX // Sample definition for PIC18 (modify to fit your own project) // Description: SD-SPI Chip Select Output bit #define SD_CS LATBbits.LATB3 // Description: SD-SPI Chip Select TRIS bit #define SD_CS_TRIS TRISBbits.TRISB3 // Description: SD-SPI Card Detect Input bit #define SD_CD PORTBbits.RB4 // Description: SD-SPI Card Detect TRIS bit #define SD_CD_TRIS TRISBbits.TRISB4 // Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTAbits.RA4 // Description: SD-SPI Write Protect Check TRIS bit #define SD_WE_TRIS TRISAbits.TRISA4 // Registers for the SPI module you want to use // Description: The main SPI control register #define SPICON1 SSP1CON1 // Description: The SPI status register #define SPISTAT SSP1STAT // Description: The SPI buffer #define SPIBUF SSP1BUF // Description: The receive buffer full bit in the SPI status register #define SPISTAT_RBF SSP1STATbits.BF // Description: The bitwise define for the SPI control register (i.e. _____bits) #define SPICON1bits SSP1CON1bits // Description: The bitwise define for the SPI status register (i.e. _____bits) #define SPISTATbits SSP1STATbits // Description: The interrupt flag for the SPI module #define SPI_INTERRUPT_FLAG PIR1bits.SSPIF // Description: The enable bit for the SPI module #define SPIENABLE SPICON1bits.SSPEN /* // Defines for the FS-USB demo board // Tris pins for SCK/SDI/SDO lines #define SPICLOCK TRISBbits.TRISB1 #define SPIIN TRISBbits.TRISB0 #define SPIOUT TRISCbits.TRISC7 // Latch pins for SCK/SDI/SDO lines #define SPICLOCKLAT LATBbits.LATB1 #define SPIINLAT LATBbits.LATB0 #define SPIOUTLAT LATCbits.LATC7 // Port pins for SCK/SDI/SDO lines #define SPICLOCKPORT PORTBbits.RB1 #define SPIINPORT PORTBbits.RB0 #define SPIOUTPORT PORTCbits.RC7 */ // Defines for the HPC Explorer board // Description: The TRIS bit for the SCK pin #define SPICLOCK TRISCbits.TRISC3 // Description: The TRIS bit for the SDI pin #define SPIIN TRISCbits.TRISC4 // Description: The TRIS bit for the SDO pin #define SPIOUT TRISCbits.TRISC5 // Description: The output latch for the SCK pin #define SPICLOCKLAT LATCbits.LATC3 // Description: The output latch for the SDI pin #define SPIINLAT LATCbits.LATC4 // Description: The output latch for the SDO pin #define SPIOUTLAT LATCbits.LATC5 // Description: The port for the SCK pin #define SPICLOCKPORT PORTCbits.RC3 // Description: The port for the SDI pin #define SPIINPORT PORTCbits.RC4 // Description: The port for the SDO pin #define SPIOUTPORT PORTCbits.RC5 // Will generate an error if the clock speed is too low to interface to the card #if (GetSystemClock() < 400000) #error System clock speed must exceed 400 kHz #endif #elif defined __PIC24F__ // Description: SD-SPI Chip Select Output bit #define SD_CS LATBbits.LATB1 // Description: SD-SPI Chip Select TRIS bit #define SD_CS_TRIS TRISBbits.TRISB1 // Description: SD-SPI Card Detect Input bit #define SD_CD PORTFbits.RF0 // Description: SD-SPI Card Detect TRIS bit #define SD_CD_TRIS TRISFbits.TRISF0 // Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTFbits.RF1 // Description: SD-SPI Write Protect Check TRIS bit #define SD_WE_TRIS TRISFbits.TRISF1 // Registers for the SPI module you want to use // Description: The main SPI control register #define SPICON1 SPI1CON1 // Description: The SPI status register #define SPISTAT SPI1STAT // Description: The SPI Buffer #define SPIBUF SPI1BUF // Description: The receive buffer full bit in the SPI status register #define SPISTAT_RBF SPI1STATbits.SPIRBF // Description: The bitwise define for the SPI control register (i.e. _____bits) #define SPICON1bits SPI1CON1bits // Description: The bitwise define for the SPI status register (i.e. _____bits) #define SPISTATbits SPI1STATbits // Description: The enable bit for the SPI module #define SPIENABLE SPISTATbits.SPIEN // Tris pins for SCK/SDI/SDO lines // Description: The TRIS bit for the SCK pin #define SPICLOCK TRISFbits.TRISF6 // Description: The TRIS bit for the SDI pin #define SPIIN TRISFbits.TRISF7 // Description: The TRIS bit for the SDO pin #define SPIOUT TRISFbits.TRISF8 // Will generate an error if the clock speed is too low to interface to the card #if (GetSystemClock() < 100000) #error Clock speed must exceed 100 kHz #endif #elif defined (__PIC32MX__) // Registers for the SPI module you want to use // #define MDD_USE_SPI_1 #define MDD_USE_SPI_2 //変更箇所 //SPI Configuration #define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) #define SPI_START_CFG_2 (SPI_ENABLE) // Define the SPI frequency #define SPI_FREQUENCY (20000000) #if defined MDD_USE_SPI_1 // Description: SD-SPI Chip Select Output bit #define SD_CS LATBbits.LATB1 // Description: SD-SPI Chip Select TRIS bit #define SD_CS_TRIS TRISBbits.TRISB1 // Description: SD-SPI Card Detect Input bit #define SD_CD PORTFbits.RF0 // Description: SD-SPI Card Detect TRIS bit #define SD_CD_TRIS TRISFbits.TRISF0 // Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTFbits.RF1 // Description: SD-SPI Write Protect Check TRIS bit #define SD_WE_TRIS TRISFbits.TRISF1 // Description: The main SPI control register #define SPICON1 SPI1CON // Description: The SPI status register #define SPISTAT SPI1STAT // Description: The SPI Buffer #define SPIBUF SPI1BUF // Description: The receive buffer full bit in the SPI status register #define SPISTAT_RBF SPI1STATbits.SPIRBF // Description: The bitwise define for the SPI control register (i.e. _____bits) #define SPICON1bits SPI1CONbits // Description: The bitwise define for the SPI status register (i.e. _____bits) #define SPISTATbits SPI1STATbits // Description: The enable bit for the SPI module #define SPIENABLE SPICON1bits.ON // Description: The definition for the SPI baud rate generator register (PIC32) #define SPIBRG SPI1BRG // Tris pins for SCK/SDI/SDO lines // Description: The TRIS bit for the SCK pin #define SPICLOCK TRISFbits.TRISF6 // Description: The TRIS bit for the SDI pin #define SPIIN TRISFbits.TRISF7 // Description: The TRIS bit for the SDO pin #define SPIOUT TRISFbits.TRISF8 //SPI library functions #define putcSPI putcSPI1 #define getcSPI getcSPI1 #define OpenSPI(config1, config2) OpenSPI1(config1, config2) #elif defined MDD_USE_SPI_2 // Description: SD-SPI Chip Select Output bit #define SD_CS LATCbits.LATC3 //変更箇所 // #define SD_CS LATBbits.LATB9 // Description: SD-SPI Chip Select TRIS bit #define SD_CS_TRIS TRISCbits.TRISC3 //変更箇所 // #define SD_CS_TRIS TRISBbits.TRISB9 // Description: SD-SPI Card Detect Input bit #define SD_CD PORTDbits.RD8 //変更箇所 // #define SD_CD PORTGbits.RG0 // Description: SD-SPI Card Detect TRIS bit #define SD_CD_TRIS TRISDbits.TRISD8 //変更箇所 //#define SD_CD_TRIS TRISGbits.TRISG0 // Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTDbits.RD9 //変更箇所 // #define SD_WE PORTGbits.RG1 // Description: SD-SPI Write Protect Check TRIS bit #define SD_WE_TRIS TRISDbits.TRISD9 //変更箇所 // #define SD_WE_TRIS TRISGbits.TRISG1 // Description: The main SPI control register #define SPICON1 SPI2CON // Description: The SPI status register #define SPISTAT SPI2STAT // Description: The SPI Buffer #define SPIBUF SPI2BUF // Description: The receive buffer full bit in the SPI status register #define SPISTAT_RBF SPI2STATbits.SPIRBF // Description: The bitwise define for the SPI control register (i.e. _____bits) #define SPICON1bits SPI2CONbits // Description: The bitwise define for the SPI status register (i.e. _____bits) #define SPISTATbits SPI2STATbits // Description: The enable bit for the SPI module #define SPIENABLE SPI2CONbits.ON // Description: The definition for the SPI baud rate generator register (PIC32) #define SPIBRG SPI2BRG // Tris pins for SCK/SDI/SDO lines // Description: The TRIS bit for the SCK pin #define SPICLOCK TRISGbits.TRISG6 // Description: The TRIS bit for the SDI pin #define SPIIN TRISGbits.TRISG7 // Description: The TRIS bit for the SDO pin #define SPIOUT TRISGbits.TRISG8 //SPI library functions #define putcSPI putcSPI2 #define getcSPI getcSPI2 #define OpenSPI(config1, config2) OpenSPI2(config1, config2) #endif // Will generate an error if the clock speed is too low to interface to the card #if (GetSystemClock() < 100000) #error Clock speed must exceed 100 kHz #endif #endif #endif #ifdef USE_CF_INTERFACE_WITH_PMP /* CompactFlash-PMP card definitions: change these to fit your application when using the PMP module to interface with CF cards */ #ifdef __18CXX #error The PIC18 architecture does not currently support PMP interface to CF cards #elif defined __dsPIC30F__ // Sample dsPIC30 defines // Description: The output latch for the CF Reset signal #define CF_PMP_RST _RD0 // Description: The TRIS bit for the CF Reset signal #define CF_PMP_RESETDIR _TRISD0 // Description: The input port for the CF Ready signal #define CF_PMP_RDY _RD12 // Description: The TRIS bit for the CF Ready signal #define CF_PMP_READYDIR _TRISD12 // Description: The input port for the CF card detect signal #define CF_PMP_CD1 _RC4 // Description: The TRIS bit for the CF card detect signal #define CF_PMP_CD1DIR _TRISC4 #elif defined __dsPIC33F__ // Sample dsPIC33 defines // Description: The output latch for the CF Reset signal #define CF_PMP_RST _RD0 // Description: The TRIS bit for the CF Reset signal #define CF_PMP_RESETDIR _TRISD0 // Description: The input port for the CF Ready signal #define CF_PMP_RDY _RD12 // Description: The TRIS bit for the CF Ready signal #define CF_PMP_READYDIR _TRISD12 // Description: The input port for the CF card detect signal #define CF_PMP_CD1 _RC4 // Description: The TRIS bit for the CF card detect signal #define CF_PMP_CD1DIR _TRISC4 #elif defined __PIC24F__ // Default case for PIC24F // Description: The output latch for the CF Reset signal #define CF_PMP_RST LATDbits.LATD0 // Description: The TRIS bit for the CF Reset signal #define CF_PMP_RESETDIR TRISDbits.TRISD0 // Description: The input port for the CF Ready signal #define CF_PMP_RDY PORTDbits.RD12 // Description: The TRIS bit for the CF Ready signal #define CF_PMP_READYDIR TRISDbits.TRISD12 // Description: The input port for the CF card detect signal #define CF_PMP_CD1 PORTCbits.RC4 // Description: The TRIS bit for the CF card detect signal #define CF_PMP_CD1DIR TRISCbits.TRISC4 #endif // Description: Defines the PMP data bus direction register #define MDD_CFPMP_DATADIR TRISE #endif #ifdef USE_MANUAL_CF_INTERFACE // Use these definitions with CF-Bit transaction.c and .h // This will manually perform parallel port transactions #ifdef __18CXX // Address lines // Description: The CF address bus output latch register (for PIC18) #define ADDBL LATA // Description: The CF address bus TRIS register (for PIC18) #define ADDDIR TRISA // Data bus // Description: The Manual CF data bus port register #define MDD_CFBT_DATABIN PORTD // Description: The Manual CF data bus output latch register #define MDD_CFBT_DATABOUT LATD // Description: The Manual CF data bus TRIS register #define MDD_CFBT_DATADIR TRISD // control bus lines // Description: The CF card chip select output latch bit #define CF_CE LATEbits.LATE1 // Description: The CF card chip select TRIS bit #define CF_CEDIR TRISEbits.TRISE1 // Description: The CF card output enable strobe latch bit #define CF_OE LATAbits.LATA5 // Description: The CF card output enable strobe TRIS bit #define CF_OEDIR TRISAbits.TRISA5 // Description: The CF card write enable strobe latch bit #define CF_WE LATAbits.LATA4 // Description: The CF card write enable strobe TRIS bit #define CF_WEDIR TRISAbits.TRISA4 // Description: The CF card reset signal latch bit #define CF_BT_RST LATEbits.LATE0 // Description: The CF card reset signal TRIS bit #define CF_BT_RESETDIR TRISEbits.TRISE0 // Description: The CF card ready signal port bit #define CF_BT_RDY PORTEbits.RE2 // Description: The CF card ready signal TRIS bit #define CF_BT_READYDIR TRISEbits.TRISE2 // Description: The CF card detect signal port bit #define CF_BT_CD1 PORTCbits.RC2 // Description: The CF card detect signal TRIS bit #define CF_BT_CD1DIR TRISCbits.TRISC2 #elif defined __dsPIC30F__ // Address lines // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32) #define ADDR0 _LATB15 // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32) #define ADDR1 _LATB14 // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32) #define ADDR2 _LATG9 // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32) #define ADDR3 _LATG8 // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32) #define ADRTRIS0 _TRISB15 // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32) #define ADRTRIS1 _TRISB14 // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32) #define ADRTRIS2 _TRISG9 // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32) #define ADRTRIS3 _TRISG8 // Data bus // Description: The Manual CF data bus port register #define MDD_CFBT_DATABIN PORTE // Description: The Manual CF data bus output latch register #define MDD_CFBT_DATABOUT PORTE // Description: The Manual CF data bus TRIS register #define MDD_CFBT_DATADIR TRISE // control bus lines // Description: The CF card chip select output latch bit #define CF_CE _RD11 // Description: The CF card chip select TRIS bit #define CF_CEDIR _TRISD11 // Description: The CF card output enable strobe latch bit #define CF_OE _RD5 // Description: The CF card output enable strobe TRIS bit #define CF_OEDIR _TRISD5 // Description: The CF card write enable strobe latch bit #define CF_WE _RD4 // Description: The CF card write enable strobe TRIS bit #define CF_WEDIR _TRISD4 // Description: The CF card reset signal latch bit #define CF_BT_RST _RD0 // Description: The CF card reset signal TRIS bit #define CF_BT_RESETDIR _TRISD0 // Description: The CF card ready signal port bit #define CF_BT_RDY _RD12 // Description: The CF card ready signal TRIS bit #define CF_BT_READYDIR _TRISD12 // Description: The CF card detect signal port bit #define CF_BT_CD1 _RC4 // Description: The CF card detect signal TRIS bit #define CF_BT_CD1DIR _TRISC4 #elif defined __dsPIC33F__ // Address lines // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32) #define ADDR0 _LATB15 // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32) #define ADDR1 _LATB14 // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32) #define ADDR2 _LATG9 // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32) #define ADDR3 _LATG8 // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32) #define ADRTRIS0 _TRISB15 // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32) #define ADRTRIS1 _TRISB14 // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32) #define ADRTRIS2 _TRISG9 // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32) #define ADRTRIS3 _TRISG8 // Data bus // Description: The Manual CF data bus port register #define MDD_CFBT_DATABIN PORTE // Description: The Manual CF data bus output latch register #define MDD_CFBT_DATABOUT PORTE // Description: The Manual CF data bus TRIS register #define MDD_CFBT_DATADIR TRISE // control bus lines // Description: The CF card chip select output latch bit #define CF_CE _RD11 // Description: The CF card chip select TRIS bit #define CF_CEDIR _TRISD11 // Description: The CF card output enable strobe latch bit #define CF_OE _RD5 // Description: The CF card output enable strobe TRIS bit #define CF_OEDIR _TRISD5 // Description: The CF card write enable strobe latch bit #define CF_WE _RD4 // Description: The CF card write enable strobe TRIS bit #define CF_WEDIR _TRISD4 // Description: The CF card reset signal latch bit #define CF_BT_RST _RD0 // Description: The CF card reset signal TRIS bit #define CF_BT_RESETDIR _TRISD0 // Description: The CF card ready signal port bit #define CF_BT_RDY _RD12 // Description: The CF card ready signal TRIS bit #define CF_BT_READYDIR _TRISD12 // Description: The CF card detect signal port bit #define CF_BT_CD1 _RC4 // Description: The CF card detect signal TRIS bit #define CF_BT_CD1DIR _TRISC4 #elif defined __PIC24F__ // Address lines // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32) #define ADDR0 LATBbits.LATB15 // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32) #define ADDR1 LATBbits.LATB14 // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32) #define ADDR2 LATGbits.LATG9 // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32) #define ADDR3 LATGbits.LATG8 // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32) #define ADRTRIS0 TRISBbits.TRISB15 // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32) #define ADRTRIS1 TRISBbits.TRISB14 // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32) #define ADRTRIS2 TRISGbits.TRISG9 // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32) #define ADRTRIS3 TRISGbits.TRISG8 // Data bus // Description: The Manual CF data bus port register #define MDD_CFBT_DATABIN PORTE // Description: The Manual CF data bus output latch register #define MDD_CFBT_DATABOUT PORTE // Description: The Manual CF data bus TRIS register #define MDD_CFBT_DATADIR TRISE // control bus lines // Description: The CF card chip select output latch bit #define CF_CE PORTDbits.RD11 // Description: The CF card chip select TRIS bit #define CF_CEDIR TRISDbits.TRISD11 // Description: The CF card output enable strobe latch bit #define CF_OE PORTDbits.RD5 // Description: The CF card output enable strobe TRIS bit #define CF_OEDIR TRISDbits.TRISD5 // Description: The CF card write enable strobe latch bit #define CF_WE PORTDbits.RD4 // Description: The CF card write enable strobe TRIS bit #define CF_WEDIR TRISDbits.TRISD4 // Description: The CF card reset signal latch bit #define CF_BT_RST PORTDbits.RD0 // Description: The CF card reset signal TRIS bit #define CF_BT_RESETDIR TRISDbits.TRISD0 // Description: The CF card ready signal port bit #define CF_BT_RDY PORTDbits.RD12 // Description: The CF card ready signal TRIS bit #define CF_BT_READYDIR TRISDbits.TRISD12 // Description: The CF card detect signal port bit #define CF_BT_CD1 PORTCbits.RC4 // Description: The CF card detect signal TRIS bit #define CF_BT_CD1DIR TRISCbits.TRISC4 #endif #endif #include <uart2.h> #endif //SD-SPI.c ファイルの修正箇所 //SDカードのソケットのライトプロテクトの動作が逆のものがあります。2010年12月のマイクロチップのライブラリは //ライトプロテクトのモードで、PICからみて下記のソケットを想定してできています。 // ・ライトプロテクトされている場合 …… 1(+3.3V) // ・ライトプロテクトされていない場合…… 0(0V) //サンハヤト鰍フCK29の場合上記論理とは逆なので下記のようにソースコードを一部変更する必要があります。 //下記は修正後のコードです。 ***************************************************************************************/ BYTE MDD_SDSPI_WriteProtectState(void) { return(!SD_WE); //修正前のコード return(SD_WE); //!が追加になっています。 } /****************************************************************************
<動作結果>
★ SDカード読み書き <PIC32MX795F512L チャンネル4>
PIC32MX795F512Lのチャンネル4(SPI4)によりSDカードを読書きする場合は、putcSPI4( ) , getcSPI4(
) , OpenSPI4( ) が SDカードのライブラリとして用意されていないので SpiPutC(SPI_CHANNEL4,
), SpiGetC(SPI_CHANNEL4, ) SpiChnOpen(SPI_CHANNEL4, ). などをつかい ライブラリファイルSD-SPI.c. も変更する必要があるようです。 以下にその例を紹介します。
<試作品の仕様>
1. PIC32MX795512Lのチャンネル4(SPI4)を用いSDカードの読み書きをおこなう
2. SDカードに12345を書込み、これを読出し液晶に表示する
<試作品回路図>(→ 回路図のpdfファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> #include <p32xxxx.h> #include <plib.h> // PIC32 peripheral library #include "1lcd_lib_C32.h" #include "FSIO.h" // configuration CPU=80MHz Peri=80MHz,HS+PLL,Divider=1/2,PLL=x20,WDT=Off #pragma config FNOSC=PRIPLL, POSCMOD=HS, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_1 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 char Buf[17]; //文字列のバッファー用レジスタ unsigned int Buf_Input[3]; //SDカード書き込み値 unsigned int Buf_SD[3]; //SDカード読込み値 int N_Write; //書き込み回数戻り値 FSFILE* pfile; //SDカードのファイルポインタ void delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do //実測: at Clock=80000000 { //delay_us(1000)→1003μsec、 delay_us(100)→102μsec、delay_us(10)→11μsec、delay_us(1)→1.6μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) delay_us(1000); } int main(void) { SYSTEMConfigPerformance(80000000); // システム最適化 // INTEnableSystemMultiVectoredInt(); //マルチベクタ方式割り込み許可 mJTAGPortEnable(DEBUG_JTAGPORT_OFF); //JTAG無効化//DDPCONbits.JTAGEN = 0; //I/OポートとしてRA0、RA1、RA4、RA5をつかう場合必須 AD1PCFG =0xFFFF; //Bポート:アナログ → デジタル//状態変化ピンとして使う場合必須 TRISBbits.TRISB15 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB14 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB13 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB12 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA10 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA9 = 0; //キャラクタ液晶ポート設定 lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); // 全消去 sprintf(Buf,"SD W/R Start2 !!");//C30とは異なり、arguement 不要 lcd_str(Buf); //液晶表示 delay_ms(1000); //// SDカードの実装とフォーマット済をチェック SD_CS = 0; // LATCbits.LATC3 = 0; //CS=0 SDカードのチップセレクトenable while(!FSInit()); //SDカードの実装とフォーマット済をチェック SD_CS = 1; // LATCbits.LATC3 = 1; //CS=1 SDカードのチップセレクトdisable lcd_clear(); // 全消去 sprintf(Buf,"Initialize OK !!");//C30とは異なり、arguement 不要 lcd_str(Buf); //液晶表示 delay_ms(1000); //// ファイルを書き込みモードでオープン SD_CS = 0; // LATCbits.LATC3 = 0; //CS=0 SDカードのチップセレクトenable pfile = FSfopen("DATA.DAT","w"); //ファイル書き込みモードでオープン 但しファイルがなければ新規ファイル作成 if(pfile == NULL) //ファイルオープン失敗の場合(SDカードにライトプロテクトがされている場合など) { lcd_clear(); sprintf(Buf,"W_ModeOpen Error"); //液晶に"W_ModeOpen Error" を表示 lcd_str(Buf); return 0; } else //ファイルオープン成功なら { lcd_clear(); sprintf(Buf,"FileOpen OK !!"); //液晶に"W_ModeOpen OK" を表示 lcd_str(Buf); lcd_cmd(0xC0); //2行目へ sprintf(Buf," (Write Mode)"); lcd_str(Buf); delay_ms(1000); } Buf_Input[0] = 12345 ; //書き込みデータをセット // Buf_Input[0] = 12345; //書き込みデータをセット N_Write = FSfwrite((const void*)Buf_Input,sizeof(Buf_Input),1,pfile);//ファイルにデータ書き込み if(N_Write == 1) //正常な場合:書き込み回数が返ってくる { lcd_clear(); sprintf(Buf,"Write OK !!"); //液晶に"Write OK !" を表示 lcd_str(Buf); delay_ms(1000); } else //異常な場合 { lcd_clear(); sprintf(Buf,"Write NG !!"); //液晶に"Write NG !" を表示 lcd_str(Buf); return 0; } FSfclose(pfile); // ファイルを閉じる SD_CS = 1; // LATCbits.LATC3 = 1; //CS=1 SDカードのチップセレクトdisable //// SDカードを読込みモードでオープン SD_CS = 0; // LATCbits.LATC3 = 0; //CS=0 SDカードのチップセレクトenable pfile = FSfopen("DATA.DAT","r"); //ファイル読込みモードでオープン if(pfile == NULL) { lcd_clear(); sprintf(Buf,"R_ModeOpen Error"); //液晶に"R_ModeOpen Error"を表示 lcd_str(Buf); return 0; } else { lcd_clear(); sprintf(Buf,"FileOpen OK !!"); //液晶に"W_ModeOpen OK" を表示 lcd_str(Buf); lcd_cmd(0xC0); //2行目へ sprintf(Buf," (Read Mode)"); lcd_str(Buf); delay_ms(1000); } FSfread(Buf_SD,sizeof(Buf_SD),1,pfile); //ファイルからデータ読込み FSfclose(pfile); //ファイルを閉じる SD_CS = 1; // LATCbits.LATC3 = 1; //CS=1 SDカードのチップセレクトdisable //// 読込みデータの表示 lcd_clear(); sprintf(Buf,"SD_DATA=%u",Buf_SD[0]); //SDカードから読み込んだデータを液晶に表示 lcd_str(Buf); lcd_cmd(0xC0); //2行目へ sprintf(Buf,"795 ch4 was used"); lcd_str(Buf); //------------------------------------------------------------------------------------------------------------------ //HardwareProfile.h //Microchip Memory Disk Drive File System #ifndef _HARDWAREPROFILE_H_ #define _HARDWAREPROFILE_H_ //クロック周波数設定 // Define your clock speed here #define RUN_AT_80MHZ #if defined(RUN_AT_48MHZ) #define GetSystemClock() 48000000UL // System clock frequency (Hz) #define GetPeripheralClock() 48000000UL // Peripheral clock frequency #define GetInstructionClock() (GetSystemClock()) // Instruction clock frequency #elif defined(RUN_AT_24MHZ) #define GetSystemClock() 24000000UL #define GetPeripheralClock() 24000000UL #define GetInstructionClock() (GetSystemClock()) #elif defined(RUN_AT_80MHZ) #define GetSystemClock() (80000000ul) //システムクロック #define GetPeripheralClock() (GetSystemClock()/2) //ペリフェラルクロック #define GetInstructionClock() (GetSystemClock()) //インストラクションクロック #else #error Choose a speed #endif // Clock values #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer #define TIMER_PERIOD 37500 // Definition for use with a tick timer // Description: Macro used to enable the SD-SPI physical layer (SD-SPI.c and .h) #define USE_SD_INTERFACE_WITH_SPI //SD カード選択・検出 //CS:チップセレクト // Description: SD-SPI Chip Select Output bit #define SD_CS LATDbits.LATD14 //LATCbits.LATC3 #define SD_CS_TRIS TRISDbits.TRISD14 // TRISCbits.TRISC3 //CD:カードディテクト // Description: SD-SPI Card Detect Input bit #define SD_CD PORTFbits.RF12 // PORTDbits.RD8 #define SD_CD_TRIS TRISFbits.TRISF12 // TRISDbits.TRISD8 //WE:ライトイネーブル Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTAbits.RA1 #define SD_WE_TRIS TRISAbits.TRISA1 //SPIコンフィギュレーション //SPI Configuration #define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) #define SPI_START_CFG_2 (SPI_ENABLE) #define SPI_FREQUENCY (400000) //SPI周波数 //Define the SPI frequency // #define SPI_FREQUENCY (20000000) //SPI周波数 //Define the SPI frequency //チャンネル4: #define SPICON1 SPI4CON //制御レジスタ #define SPISTAT SPI4STAT //SPIステータスレジスタ status register #define SPIBUF SPI4BUF //SPIバッファレジスタ #define SPISTAT_RBF SPI4STATbits.SPIRBF //受信バッファ満杯ビット// The receive buffer full bit in the SPI status register #define SPICON1bits SPI4CONbits //ビット単位の定義(制御レジスタ)The bitwise define for the SPI control register (i.e. _____bits) #define SPISTATbits SPI4STATbits //ビット単位の定義(ステータスレジスタ) //The bitwise define for the SPI status register (i.e. _____bits) #define SPIENABLE SPI4CONbits.ON //SPIモジュール イネーブルビット //The enable bit for the SPI module #define SPIBRG SPI4BRG //ボーレートジェネレータ//The definition for the SPI baud rate generator register (PIC32) //SCK,SDI,SDOピンアサイン //Tris pins for SCK/SDI/SDO lines #define SPICLOCK TRISFbits.TRISF12 //TRISGbits.TRISG6 //SCK #define SPIIN TRISFbits.TRISF4 //PICのSDI4 // TRISGbits.TRISG7 //PICのSDI2 #define SPIOUT TRISFbits.TRISF5 //PICのSDO4 // TRISGbits.TRISG8 //SDO //SPIライブラリ関数 //library functions // #define putcSPI putcSPI4 //putcSPI2 // #define getcSPI getcSPI4 //getcSPI2 // #define OpenSPI(config1, config2) OpenSPI4(config1, config2) //OpenSPI2(config1, config2) //システムクロックが遅すぎる場合のエラー表示 // Will generate an error if the clock speed is too low to interface to the card #if (GetSystemClock() < 100000) #error Clock speed must exceed 100 kHz #endif #include <uart2.h> #endif //------------------------------------------------------------------------------------------------------------------------------- //SD-SPI.c //SD-SPI.cファイルは 以下を変更しています。
........
........
void InitSPISlowMode(void)
{
#if defined __C30__ || defined __C32__
#ifdef __PIC32MX__
SpiChnOpen(SPI_CHANNEL4,SPI_OPEN_MSTEN|SPI_OPEN_CKP_HIGH|SPI_OPEN_SMP_END|SPI_OPEN_MODE8,128);
//OpenSPI(SPI_START_CFG_1, SPI_START_CFG_2);
SPIBRG = SPICalutateBRG(GetPeripheralClock(), 400000);
#else //else C30 = PIC24/dsPIC devices
WORD spiconvalue = 0x0003;
WORD timeout;
.......
.......
}
.......
.......
BYTE MDD_SDSPI_ReadMedia(void)
{
#ifdef __C32__
SpiChnPutC(SPI_CHANNEL4 , (BYTE)0xFF); //putcSPI((BYTE)0xFF);
return SpiChnGetC(SPI_CHANNEL4); //return (BYTE)getcSPI();
#elif defined __18CXX
BYTE clear;
clear = SPIBUF;
SPI_INTERRUPT_FLAG = 0;
SPIBUF = 0xFF;
.........
.........
}
unsigned char WriteSPIM( unsigned char data_out )
{
#ifdef __PIC32MX__
BYTE clear;
SpiChnPutC(SPI_CHANNEL4 , (BYTE)data_out); //putcSPI((BYTE)data_out);
clear = SpiChnGetC(SPI_CHANNEL4); // clear = getcSPI();
return ( 0 ); // return non-negative#
#elif defined __18CXX
BYTE clear;
clear = SPIBUF;
SPI_INTERRUPT_FLAG = 0;
SPIBUF = data_out;
........
........
}
.......
....... //---------------------------------------------------------------------------------------- //************************************************************************* //インクルードファイル 1lcd_lib_C32.h //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************* #include <p32xxxx.h> //#include <proc/p32mx795f512l.h> //MX795はイニシャライズループを抜けられない //#include <proc/p32mx360f512l.h> //PIC32MX460F512L #define Clock 80000000 // 単位はHzで指定 // LCDポート設定 #define lcd_port_DB7 LATBbits.LATB15 //LCDのDB7(14番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB6 LATBbits.LATB14 //LCDのDB6(13番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB5 LATBbits.LATB13 //のDB5(12番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB4 LATBbits.LATB12 //LCDのDB4(11番ピン)に接続されつPIC側ポート番号設定 #define lcd_rs LATAbits.LATA9 //LCDのrs(4番ピン)に接続されるPIC側ポート番号設定 #define lcd_stb LATAbits.LATA10 //LCDのstb(6番ピン)に接続されるPIC側ポート番号設定 void lcd_out(char code, char flag); void lcd_data(char asci); void lcd_cmd(char cmd); void lcd_clear(void); void lcd_init(void); void lcd_str(char *str); //---------------------------------------------------------------------------------------- //************************************************************************** //インクルードファイル 1lcd_lib_C32.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C32コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C32.h" void lcd_delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void lcd_delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) lcd_delay_us(1000); } //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 lcd_delay_us(1); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) lcd_delay_us(1); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 lcd_delay_us(50); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 lcd_delay_ms(2); // 2msec待ち else lcd_delay_us(50); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { lcd_delay_ms(20); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(5); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set lcd_delay_ms(1); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home }
<動作結果>
SDカード読み書き <PIC32MZ2048ECH100編>
Harmonyを使って SDカードの読み書きを行う場合、 ファイル名として ロングファイル名が扱えます。
<試作品の仕様>
1. PIC32MZとハーモニーをつかいSDカードの読み書きをおこなう
2. ファイル名は myFileName01.txt とする
3. SDカードがカードスロットに挿入されているかチェックし 液晶に表示を行う
4. ファイルがオープンできたら液晶に表示する。
5. ファイルを 上書き可のモードで開き ”Hellow Worold !!" のテキストをファイルに書き込む
6. ファイルを閉じる
7. ファイルを読み込みモードで開き、書き込まれている内容を液晶に表示する
開発環境 Harmony ver 1.02 XC32 ver.1.34 MPLABX ver.2.35 PIC32MZ2048ECH100
revision 5
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //以下、main().c //---------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony Project Main Source File Company: Microchip Technology Inc. File Name: main.c Summary: This file contains the "main" function for an MPLAB Harmony project. Description: This file contains the "main" function for an MPLAB Harmony project. The "main" function calls the "SYS_Initialize" function to initialize the state machines of all MPLAB Harmony modules in the system and it calls the "SYS_Tasks" function from within a system-wide "super" loop to maintain their correct operation. These two functions are implemented in configuration-specific files (usually "system_init.c" and "system_tasks.c") in a configuration-specific folder under the "src/system_config" folder within this project's top-level folder. An MPLAB Harmony project may have more than one configuration, each contained within it's own folder under the "system_config" folder. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. //Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include <stddef.h> // Defines NULL #include <stdbool.h> // Defines true #include <stdlib.h> // Defines EXIT_FAILURE #include "system/common/sys_module.h" // SYS function prototypes // ***************************************************************************** // ***************************************************************************** // Section: Main Entry Point // ***************************************************************************** // ***************************************************************************** int main ( void ) { /* Initialize all MPLAB Harmony modules, including application(s). */ SYS_Initialize ( NULL ); while ( true ) { /* Maintain state machines of all polled MPLAB Harmony modules. */ SYS_Tasks ( ); } /* Execution should not come here during normal operation */ return ( EXIT_FAILURE ); } /******************************************************************************* End of File */ //以下、app.c //--------------------------------------------------------------------------------------- /******************************************************************************* MPLAB Harmony Application Source File Company: Microchip Technology Inc. File Name: app.c Summary: This file contains the source code for the MPLAB Harmony application. Description: This file contains the source code for the MPLAB Harmony application. It implements the logic of the application's state machine and it may call API routines of other MPLAB Harmony modules in the system, such as drivers, system services, and middleware. However, it does not call any of the system interfaces (such as the "Initialize" and "Tasks" functions) of any of the modules in the system or make any assumptions about when those functions are called. That is the responsibility of the configuration-specific system files. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include "app.h" #include "1lcd_lib_C32.h" int delay_Clock = 200000000; //200MHz char Buf[17]; //1液晶表示バッファー int SdMode = 0; //SDカードに対する操作モード unsigned int Buf_Input[3]; //SDカード書き込み値 char Hellow[] = "Hellow World !!"; char myFileName01[] = "myFileName01.txt"; unsigned int Buf_SD[3]; //SDカード読込み値 int N_Write; //書き込み回数戻り値 SYS_FS_HANDLE fileHandle; //ファイルハンドル SYS_FS_HANDLE fileHandle2; //ファイルハンドル char tempBuf[20]; char tempBuf2[20]; char tempBuf3[20]; int eof; int size; char* str1; void delay_us(volatile unsigned int usec) //1μsec遅延 { volatile int count; count = (int)(delay_Clock/20000000)*usec; do //実測 at 200MH (Clock=200000000) { //delay_us(1000):1000.4μsec delay_us(100):100.6μsec delay_us(10):10.5μsec delay_us(1):1.5μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void delay_ms(volatile unsigned int msec) //1msec遅延 { volatile unsigned int i; //実測:at200MH (Clock=200000000)//delay_ms(1): 1.0006msec delay_ms(100):100.04msec for(i=0; i<msec; i++) delay_us(1000); } // ***************************************************************************** // ***************************************************************************** // Section: Global Data Definitions // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* Application Data Summary: Holds application data Description: This structure holds the application's data. Remarks: This structure should be initialized by the APP_Initialize function. Application strings and buffers are be defined outside this structure. */ APP_DATA appData; // ***************************************************************************** // ***************************************************************************** // Section: Application Callback Functions // ***************************************************************************** // ***************************************************************************** /* TODO: Add any necessary callback funtions. */ // ***************************************************************************** // ***************************************************************************** // Section: Application Local Functions // ***************************************************************************** // ***************************************************************************** /* TODO: Add any necessary local functions. */ // ***************************************************************************** // ***************************************************************************** // Section: Application Initialization and State Machine Functions // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void APP_Initialize ( void ) Remarks: See prototype in app.h. */ void APP_Initialize ( void ) { /* Place the App state machine in its initial state. */ appData.state = APP_STATE_INIT; /* TODO: Initialize your application's state machine and other * parameters. */ lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"SD card Start !! ");// lcd_str(Buf); //液晶表示 lcd_cmd(0xC0); //2行目の先頭へ sprintf(Buf," "); // lcd_str(Buf); // 開始メッセージ1行目表示 delay_ms(2000); } /****************************************************************************** Function: void APP_Tasks ( void ) Remarks: See prototype in app.h. */ void APP_Tasks ( void ) { /* Check the application's current state. */ int ix = 0; switch(SdMode) { //------------------------------------------------------------------------------------------------- case 0: //カード挿入検出・ライトプロテクトチェック if(SYS_FS_Mount("/dev/mmcblka1", "/mnt/myDrive", FAT, 0, NULL) != 0) //ファイルシステムが搭載されているか? //mmcblka1:SDカード //変更不可 //myDrive: 変更不可 { //失敗の場合 //カードがマウントされていても8回以上実行される lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"SD notMounted ");// lcd_str(Buf); //液晶表示 SdMode = 0; } else { //成功の場合 lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"SD mounted ");// lcd_str(Buf); //液晶表示 delay_ms(2000); //ライトプロテクトをチェック if(PORTBbits.RB9 != 0) //ライトプロテクトの場合 // writeProtectStatus = DRV_SDCARD_WriteProtectionIsEnabled(fileHandle); // if(PORTFbits.RF1 != 0) //ライトプロテクトの場合 // writeProtectStatus = DRV_SDCARD_WriteProtectionIsEnabled(fileHandle); { lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"WriteProtected "); //液晶に"Write OK !" を表示 lcd_str(Buf); while(1); } else { //ライトプロテクトが解除されている場合 lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"WriteReleased "); //液晶に"Write OK !" を表示 lcd_str(Buf); delay_ms(3000); } SdMode = 1; } break; //-------------------------------------------------------------------------------------------- case 1: // ファイルを書き込みモードでオープン 但しファイルがなければ新規ファイル作成 fileHandle = SYS_FS_FileOpen(myFileName01, (SYS_FS_FILE_OPEN_WRITE)); if(fileHandle == SYS_FS_HANDLE_INVALID) { //ファイルオープンエラーの場合 lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"FileOpen_w failed ");// lcd_str(Buf); //液晶表示 while(1); } else { lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"FileOpen_w OK !! "); //液晶に"W_ModeOpen OK" を表示 lcd_str(Buf); //液晶表示 delay_ms(2000); SdMode = 2; } break; //------------------------------------------------------------------------------------------- case 2: //データの書き込み N_Write = SYS_FS_FileWrite(fileHandle, Hellow, sizeof(Hellow));//ファイルにデータ書き込み if(N_Write != -1) //正常な場合:書き込み回数が返ってくる { lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"Write OK !! "); //液晶に"Write OK !" を表示 lcd_str(Buf); delay_ms(2000); } else //異常な場合 { lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"Write NG !! "); //液晶に"Write NG !" を表示 lcd_str(Buf); while(1); } SYS_FS_FileClose(fileHandle); //ファイルクローズ SdMode = 3; break; //------------------------------------------------------------------------------------------ case 3: //読出しファイルオープン fileHandle2 = SYS_FS_FileOpen(myFileName01, (SYS_FS_FILE_OPEN_READ)); if(fileHandle2 == -1) //ファイルオープン 失敗の場合 //if(fileHandle2 == SYS_FS_HANDLE_INVALID) //ファイルオープン 失敗の場合 { lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"FileOpen_r failed");// lcd_str(Buf); //液晶表示 while(1); } else SdMode = 4; break; //--------------------------------------------------------------- case 4: //ファイル読出し・表示 do { SYS_FS_FileRead(fileHandle2, tempBuf, 1); //1バイトづつ読出し eof = SYS_FS_FileEOF(fileHandle2); //EOFチェック if(eof != true) { tempBuf2[ix] = tempBuf[0]; ix++; } }while(eof != true); //ファイルエンドでない場合は、繰り返し読む tempBuf2[ix] = '\0'; //文字列終端処理 SYS_FS_FileClose(fileHandle2); //ファイルを閉じる lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"%s ",myFileName01); //液晶に"Write OK !" を表示 lcd_str(Buf); lcd_cmd(0xC0); //2目の先頭へ sprintf(tempBuf3,"%s ",tempBuf2); lcd_str(tempBuf3); SdMode = 5; break; case 5: delay_ms(10000); break; //------------------------------------------------------------------------------ default: break; } } /******************************************************************************* End of File */ //以下、system_init.c //---------------------------------------------------------------------------------- /******************************************************************************* System Initialization File File Name: system_init.c Summary: This file contains source code necessary to initialize the system. Description: This file contains source code necessary to initialize the system. It implements the "SYS_Initialize" function, configuration bits, and allocates any necessary global system resources, such as the systemObjects structure that contains the object handles to all the MPLAB Harmony module objects in the system. *******************************************************************************/ // DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ // DOM-IGNORE-END // ***************************************************************************** // ***************************************************************************** // Section: Included Files // ***************************************************************************** // ***************************************************************************** #include "system_config.h" #include "system_definitions.h" #include "app.h" // **************************************************************************** // **************************************************************************** // Section: Configuration Bits // **************************************************************************** // **************************************************************************** //----------------------------------------------------------------------- //DEVCFG0レジスタ #pragma config EJTAGBEN = NORMAL #pragma config DBGPER = ALLOW_PG2 #pragma config FSLEEP = OFF #pragma config FECCCON = OFF_UNLOCKED #pragma config BOOTISA = MIPS32 #pragma config TRCEN = OFF #pragma config ICESEL = ICS_PGx2 #pragma config JTAGEN = OFF //JTAG ポート Disable #pragma config DEBUG = OFF //---------------------------------------------------------------------- //DEVCFG1レジスタ #pragma config FNOSC = SPLL //PLL回路(システムPLL)選択 //システム発振回路 //内蔵FRC(8MHz)選択の場合:FNOSC = FRCDIV //Oscillator Selection Bits (Fast RC Osc w/Div-by-N (FRCDIV)) #pragma config FDMTEN = OFF //デッドマンタイマ OFF (Deadman Timer is disabled) //#pragma config DMTINTV = WIN_127_128 // DMT Count Window Interval (Window/Interval value is 127/128 counter value) #pragma config FSOSCEN = OFF // 副発振器OFF //Secondary Oscillator Enable (Disable SOSC) #pragma config IESO = OFF //ウェイクアップ時の2段速度スタートアップ // Internal/External Switch Over (Disabled) #pragma config POSCMOD = HS //HS: ハイスピードレゾネータモード // HS(High Speed Resonator Operation) Oscillator mode selected //EC: 外部発振器 //EC(External Clock Input Operation) mode selected // Primary Oscillator Configuration (Primary osc disabled) #pragma config OSCIOFNC = OFF //OSCCOピン出力無効 #pragma config FCKSM = CSECME //クロック発振:切替及びモニタ有効 //主発振器失陥でFRC(内蔵高速発振器)に切替 //FSCM(Fail Safe Clock Monitor)制御 #pragma config FWDTEN = OFF // ウォッチドックタイマ OFF //Watchdog Timer Disable //#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576) //#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming) //#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode) //#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%) //-------------------------------------------------------------------------------------------------------------------- // DEVCFG2レジスタ //システムクロック:200MHz //ペリフェラル周波数://default: 100MHz //PBxDIVで8系統毎に設定変更可 //PBxDIV: PERIPHERAL BUS CLOCK DIVISOR CONTROL レジスタのPBDIV<6:0>: Peripheral Bus Clock Divisor Control ビットで設定 #pragma config FPLLRNG = RANGE_5_10_MHZ //PLL Input周波数入力範囲設定// System PLL Input Range (5-10 MHz Input) //8(= 24/3)MHz故 #pragma config FPLLIDIV = DIV_3 //PLL入力側での分周: 1/3 // PLL Input周波数 = 24MHz ÷ 3 = 8MHz // System PLL Input Divider (1x Divider) //#pragma config FPLLICLK = PLL_POSC //主発振回路選択 //内蔵FRC(8MHz)の場合はFPLLICLK = PLL_FRC// System PLL Input Clock Selection (POSC is input to the System PLL) #pragma config FPLLICLK = PLL_FRC //内蔵高速発振器選択 //★★★ バグ有 主発振回路選択の時、FPLLICLK = PLL_POSCではなくFPLLICLK = PLL_FRCを選択する。(at ver.1.33 XC32) #pragma config FPLLMULT = MUL_50 //PLL倍率:50倍 //8MHz x 50 = 400MHz //System PLL Multiplier (PLL Multiply by 50) #pragma config FPLLODIV = DIV_2 //PLL出力側での分周: 1/2 //システムクロック = 400MHz ÷ 2 = 200MHz #pragma config UPLLFSEL = FREQ_24MHZ //USBのPLL入力を 24MHz→12MHzに変換 // USB PLL Input Frequency Selection (USB PLL input is 12 MHz) #pragma config UPLLEN = ON //USBのPLL変換:イネーブル // USB PLL Enable (USB PLL is enabled) //-------------------------------------------------------------------------------------------------------------------------- //DEVCFG3レジスタ #pragma config USERID = 0xffff #pragma config FMIIEN = ON #pragma config FETHIO = ON #pragma config PGL1WAY = ON #pragma config PMDL1WAY = ON #pragma config IOL1WAY = ON #pragma config FUSBIDIO = ON /*** BF1SEQ0 ***/ #pragma config TSEQ = 0xffff #pragma config CSEQ = 0xffff // ***************************************************************************** // ***************************************************************************** // Section: Library/Stack Initialization Data // ***************************************************************************** // *****************************************************************************/ // ***************************************************************************** // ***************************************************************************** // Section: Driver Initialization Data // ***************************************************************************** // ***************************************************************************** //<editor-fold defaultstate="collapsed" desc="DRV_Timer Configuration"> /*** TMR Driver Initialization Data ***/ const DRV_TMR_INIT drvTmr0InitData = { .moduleInit.sys.powerState = DRV_TMR_POWER_STATE_IDX0, .tmrId = DRV_TMR_PERIPHERAL_ID_IDX0, .clockSource = DRV_TMR_CLOCK_SOURCE_IDX0, .prescale = DRV_TMR_PRESCALE_IDX0, .mode = DRV_TMR_OPERATION_MODE_IDX0, .interruptSource = DRV_TMR_INTERRUPT_SOURCE_IDX0, .asyncWriteEnable = false, }; // </editor-fold> //<editor-fold defaultstate="collapsed" desc="DRV_SPI Configuration"> /*** SPI Driver Initialization Data ***/ /*** Index 0 ***/ DRV_SPI_INIT drvSpi0InitData = { .spiId = DRV_SPI_SPI_ID_IDX0, .taskMode = DRV_SPI_TASK_MODE_IDX0, .spiMode = DRV_SPI_SPI_MODE_IDX0, .allowIdleRun = DRV_SPI_ALLOW_IDLE_RUN_IDX0, .spiProtocolType = DRV_SPI_SPI_PROTOCOL_TYPE_IDX0, .commWidth = DRV_SPI_COMM_WIDTH_IDX0, .spiClk = DRV_SPI_SPI_CLOCK_IDX0, .baudRate = DRV_SPI_BAUD_RATE_IDX0, .bufferType = DRV_SPI_BUFFER_TYPE_IDX0, .clockMode = DRV_SPI_CLOCK_MODE_IDX0, .inputSamplePhase = DRV_SPI_INPUT_PHASE_IDX0, .txInterruptSource = DRV_SPI_TX_INT_SOURCE_IDX0, .rxInterruptSource = DRV_SPI_RX_INT_SOURCE_IDX0, .errInterruptSource = DRV_SPI_ERROR_INT_SOURCE_IDX0, .queueSize = DRV_SPI_QUEUE_SIZE_IDX0, .jobQueueReserveSize = DRV_SPI_RESERVED_JOB_IDX0, }; // </editor-fold> //<editor-fold defaultstate="collapsed" desc="SYS_TMR Configuration"> /*** TMR Service Initialization Data ***/ const SYS_TMR_INIT sysTmrInitData = { .moduleInit = {SYS_MODULE_POWER_RUN_FULL}, .drvIndex = DRV_TMR_INDEX_0, .tmrFreq = 1000, }; // </editor-fold> //<editor-fold defaultstate="collapsed" desc="DRV_SDCARD Configuration"> /*** SDCARD Driver Initialization Data ***/ const DRV_SDCARD_INIT drvSDCardInit = { .spiId = SPI_ID_6, .spiIndex = 0, .sdcardSpeedHz = 20000000, .spiClk = CLK_BUS_PERIPHERAL_1, .sdCardPinActiveLogic = SDCARD_DETECTION_LOGIC_ACTIVE_LOW, .cardDetectPort = PORT_CHANNEL_F, .cardDetectBitPosition = PORTS_BIT_POS_12, .writeProtectPort = PORT_CHANNEL_B, .writeProtectBitPosition = PORTS_BIT_POS_9, .chipSelectPort = PORT_CHANNEL_B, .chipSelectBitPosition = PORTS_BIT_POS_13, }; // </editor-fold> // ***************************************************************************** // ***************************************************************************** // Section: System Data // ***************************************************************************** // ***************************************************************************** /* Structure to hold the object handles for the modules in the system. */ SYSTEM_OBJECTS sysObj; // ***************************************************************************** // ***************************************************************************** // Section: Module Initialization Data // ***************************************************************************** // ***************************************************************************** //<editor-fold defaultstate="collapsed" desc="SYS_DEVCON Configuration"> /*** System Device Control Initialization Data ***/ const SYS_DEVCON_INIT sysDevconInit = { .moduleInit = {0}, }; // </editor-fold> //<editor-fold defaultstate="collapsed" desc="SYS_FS Configuration"> /*** File System Initialization Data ***/ const SYS_FS_REGISTRATION_TABLE sysFSInit [ SYS_FS_MAX_FILE_SYSTEM_TYPE ] = { { .nativeFileSystemType = FAT, .nativeFileSystemFunctions = &FatFsFunctions } }; // </editor-fold> // ***************************************************************************** // ***************************************************************************** // Section: Static Initialization Functions // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** // Section: System Initialization // ***************************************************************************** // ***************************************************************************** /******************************************************************************* Function: void SYS_Initialize ( SYS_INIT_DATA *data ) Summary: Initializes the board, services, drivers, application and other modules. Remarks: See prototype in system/common/sys_module.h. */ void SYS_Initialize ( void* data ) { /* Core Processor Initialization */ SYS_CLK_Initialize( NULL ); sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit); SYS_DEVCON_PerformanceConfig(SYS_CLK_SystemFrequencyGet()); SYS_PORTS_Initialize(); /* Initialize Drivers */ sysObj.drvTmr0 = DRV_TMR_Initialize(DRV_TMR_INDEX_0, (SYS_MODULE_INIT *)&drvTmr0InitData); SYS_INT_VectorPrioritySet(INT_VECTOR_T9, INT_PRIORITY_LEVEL1); SYS_INT_VectorSubprioritySet(INT_VECTOR_T9, INT_SUBPRIORITY_LEVEL0); /*** SPI Driver Index 0 initialization***/ SYS_INT_VectorPrioritySet(DRV_SPI_TX_INT_VECTOR_IDX0, DRV_SPI_TX_INT_PRIORITY_IDX0); SYS_INT_VectorSubprioritySet(DRV_SPI_TX_INT_VECTOR_IDX0, DRV_SPI_TX_INT_SUB_PRIORITY_IDX0); SYS_INT_VectorPrioritySet(DRV_SPI_RX_INT_VECTOR_IDX0, DRV_SPI_RX_INT_PRIORITY_IDX0); SYS_INT_VectorSubprioritySet(DRV_SPI_RX_INT_VECTOR_IDX0, DRV_SPI_RX_INT_SUB_PRIORITY_IDX0); SYS_INT_VectorPrioritySet(DRV_DRV_SPI_ERROR_INT_VECTOR_IDX0, DRV_SPI_ERROR_INT_PRIORITY_IDX0); SYS_INT_VectorSubprioritySet(DRV_DRV_SPI_ERROR_INT_VECTOR_IDX0, DRV_SPI_ERROR_INT_SUB_PRIORITY_IDX0); sysObj.spiObjectIdx0 = DRV_SPI_Initialize(0, (const SYS_MODULE_INIT * const)&drvSpi0InitData); sysObj.drvSDCard = DRV_SDCARD_Initialize(DRV_SDCARD_INDEX_0,(SYS_MODULE_INIT *)&drvSDCardInit); /* Initialize System Services */ SYS_INT_Initialize(); /*** TMR Service Initialization Code ***/ sysObj.sysTmr = SYS_TMR_Initialize(SYS_TMR_INDEX_0, (const SYS_MODULE_INIT * const)&sysTmrInitData); SYS_FS_Initialize( (const void *) sysFSInit ); /* Initialize Middleware */ /* Enable Global Interrupts */ SYS_INT_Enable(); /* Initialize the Application */ APP_Initialize(); } /******************************************************************************* End of File */ //以下、sys_ports_static.c //--------------------------------------------------------------------------------------- /******************************************************************************* SYS PORTS Static Functions for PORTS System Service Company: Microchip Technology Inc. File Name: sys_ports_static.c Summary: SYS PORTS static function implementations for the Ports System Service. Description: The Ports System Service provides a simple interface to manage the ports on Microchip microcontrollers. This file defines the static implementation for the Ports System Service. Remarks: Static functions incorporate all system ports configuration settings as determined by the user via the Microchip Harmony Configurator GUI. It provides static version of the routines, eliminating the need for an object ID or object handle. *******************************************************************************/ //DOM-IGNORE-BEGIN /******************************************************************************* Copyright (c) 2013 released Microchip Technology Inc. All rights reserved. Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement). You should refer to the license agreement accompanying this Software for additional information regarding your rights and obligations. SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. *******************************************************************************/ //DOM-IGNORE-END #include "system_config.h" #include "peripheral/ports/plib_ports.h" #include "peripheral/int/plib_int.h" void SYS_PORTS_Initialize(void) { //SDカード関係 //CS TRISBbits.TRISB13 = 0; //RB13 CS: out ANSELBbits.ANSB13 = 0; //RB13 デジタルモード // TRISAbits.TRISA1 = 0; //RA1 CS: out // ANSELAbits.ANSA1 = 0; //RA1 デジタルモード //CD TRISFbits.TRISF12 = 1; //RF12 CD: in ANSELFbits.ANSF12 = 0; //RF12 デジタルモード CNPUFbits.CNPUF12 = 1; //RF12 プルアップ //CD //TRISBbits.TRISB8 = 1; //RB8 CD: in //ANSELBbits.ANSB8 = 0; //RB8 デジタルモード //CNPUBbits.CNPUB8 = 1; //RB8 プルアップ //CD //WP TRISBbits.TRISB9 = 1; //RB9 WP: in ANSELBbits.ANSB9 = 0; //RB9 デジタルモード CNPUCbits.CNPUC2 = 1; //RB9 プルアップ // //SPI6リマッピング //SDI // PPS Input Remapping TRISFbits.TRISF13 = 1; //in ANSELFbits.ANSF13 = 0; //必須 //デジタルモード PLIB_PORTS_RemapInput(PORTS_ID_0, INPUT_FUNC_SDI6, INPUT_PIN_RPF13 ); //SDI6 //RF13 // SDI6Rbits.SDI6R = 0b1001; //RPF13ピンに SDI6(入力)を割り付け //SDO // PPS Output Remapping TRISBbits.TRISB15 = 0; ANSELBbits.ANSB15 = 0; //必須 //デジタルモード PLIB_PORTS_RemapOutput(PORTS_ID_0, OUTPUT_FUNC_SDO6, OUTPUT_PIN_RPB15 ); //SDO6 //RB15 // TRISFbits.TRISF12 = 0; // ANSELFbits.ANSF12 = 0; //必須 //デジタルモード // PLIB_PORTS_RemapOutput(PORTS_ID_0, OUTPUT_FUNC_SDO6, OUTPUT_PIN_RPF12 ); //SDO6 //RF12 // RPF12Rbits.RPF12R = 0b1010; //RPF12ピンに SDO6の出力を割り付け } /******************************************************************************* End of File */ //以下、1lcd_lib_C32.h //------------------------------------------------------------------------------------- //************************************************************************* //インクルードファイル 1lcd_lib_C32.h //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //XC32コンパイラ対応等で変更したものです。 //************************************************************************* #include <p32xxxx.h> #define lcd_Clock 200000000 // 単位はHzで指定 //LCDポート出力モード設定 #define lcd_port_DB7_Config() TRISAbits.TRISA1 = 0 #define lcd_port_DB6_Config() TRISBbits.TRISB11 = 0 #define lcd_port_DB5_Config() TRISAbits.TRISA10 = 0 #define lcd_port_DB4_Config() TRISAbits.TRISA9 = 0 #define lcd_rs_Config() TRISBbits.TRISB6 = 0 #define lcd_stb_Config() TRISBbits.TRISB7 = 0 //LCDポートデジタルポート設定 #define lcd_port_DB7_Digital() ANSELAbits.ANSA1 = 0 #define lcd_port_DB6_Digital() ANSELBbits.ANSB11 = 0 #define lcd_port_DB5_Digital() ANSELAbits.ANSA10 = 0 #define lcd_port_DB4_Digital() ANSELAbits.ANSA9 = 0 #define lcd_rs_Digital() ANSELBbits.ANSB6 = 0 #define lcd_stb_Digiata() ANSELBbits.ANSB7 = 0 // LCDポート出力 #define lcd_port_DB7 LATAbits.LATA1 //LCDのDB7(14番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB6 LATBbits.LATB11 //LCDのDB6(13番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB5 LATAbits.LATA10 //のDB5(12番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB4 LATAbits.LATA9 //LCDのDB4(11番ピン)に接続されつPIC側ポート番号設定 #define lcd_rs LATBbits.LATB6 //LCDのrs(4番ピン)に接続されるPIC側ポート番号設定 #define lcd_stb LATBbits.LATB7 //LCDのstb(6番ピン)に接続されるPIC側ポート番号設定 void lcd_out(char code, char flag); void lcd_data(char asci); void lcd_cmd(char cmd); void lcd_clear(void); void lcd_init(void); void lcd_str(char *str); //以下、1lcd_lib_C32.c //---------------------------------------------------------------------------------------------- //************************************************************************** //インクルードファイル 1lcd_lib_C32.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //XC32コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C32コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C32.h" void lcd_delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(lcd_Clock/20000000)*usec; do //実測: at 200MH (Clock=200000000) { //delay_us(1000)→1000.4μsec、 delay_us(100)→100.6μsec、delay_us(10)→10.5μsec、delay_us(1)→1.5μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void lcd_delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) lcd_delay_us(1000); } //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 lcd_delay_us(3); //3μsecウェイト // lcd_delay_us(1); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) lcd_delay_us(3); //3μsecウェイト // lcd_delay_us(1); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 lcd_delay_us(50); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 lcd_delay_ms(2); // 2msec待ち else lcd_delay_us(50); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { //LCDポート出力モード設定 lcd_port_DB7_Config(); lcd_port_DB6_Config(); lcd_port_DB5_Config(); lcd_port_DB4_Config(); lcd_rs_Config(); lcd_stb_Config(); //LCDポートデジタルポート設定 lcd_port_DB7_Digital(); lcd_port_DB6_Digital(); lcd_port_DB5_Digital(); lcd_port_DB4_Digital(); lcd_rs_Digital(); lcd_stb_Digiata(); lcd_delay_ms(20); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(5); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set lcd_delay_ms(1); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home }
<動作結果>
1. ピクチャー
ステップ | 液晶表示 | ||
@ | SDカードスロットに SDカード挿入を確認 | ||
A | ファイルオープン成功 | ||
B | 書き込み成功 | ||
C | 読み出し内容表示 液晶1行目: ファイル名 液晶2行目: 読み出し内容 |
2. 動画(YouTube)
★ ADコンバータ値読み書き <dsPIC C30編>
ADコンバータ入力値を読み込んでのSDカードへ書込み、そしてこのSDカード内のADコンバータ値を読み出して
DAコンバータに同じ時間軸で再現する例を紹介します。
<試作品仕様>
@外部発振器からの三角波(周波数:1Hz Vp-p:0−4V)をAD変換してリアルタイムでSDカードに書き込む
A1000個のデータをSDカードに書き込んだら書き込みを終了して、SDカードから書き込んだデータを読み出してリアル
タイムでDAコンバータMCP4822に出力する。
B書き込み及び読み出しのサンプリング周波数は100Hzとする。
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> ///************************************************************/ // ADコンバータ値をSDカードに書き込み // その後 SDカード読込 dsPIC30F4013 //************************************************************/ // MPLAB プロジェクトへの追加ファイル // Source Filesフォルダ FSIO.c // SD-SPI.c // 1lcd_lib_C30.c // SD R_W AD 4013.c // Header Filesフォルダ FScohfig.h // FSDefs.h // FSIO.h // GenericTypeDefs.h // SD-SPI.h // 1lcd_lib_C30.h // Linker Scriptフォルダ p30f4013.gld // Library Filesフォルダ lib30F4013-coff.a #include "p30f4013.h" #include "1lcd_lib_C30.h" #include "adc12.h" #include "stdio.h" #include <timer.h> #include "FSIO.h" _FOSC(CSW_FSCM_OFF & XT_PLL8); // (10MHz)x8=80MHz _FWDT(WDT_OFF); _FBORPOR(PBOR_ON & BORV_42 & PWRT_64 & MCLR_EN); _FGS(CODE_PROT_OFF); unsigned int Config1 = //ADCON1レジスタの設定 ADC_MODULE_ON & //ADON bit15=1 : ADコンバータモジュール → ON //AD Module On/Off ADC_IDLE_CONTINUE & //ADSIL bit13=0 : アイドル時の動作 → 動作継続 //Idle Mode Operation ADC_FORMAT_INTG & //FORM bit9-8=00 :出力データのフォーマット → 整数 //Result Output Format ADC_CLK_AUTO & //SSRC bit5-7=111 :変換開始トリガ設定 //Conversion Trigger Source // →ADCON3のSAMCによるクロック(サンプルホールド)が終了後変換自動開始 ADC_AUTO_SAMPLING_OFF & //ASAM bit2=1 : ADサンプリング自動開始→手動開始 //Auto Sampling Select ADC_SAMP_OFF; //SAMP bit1=0 : サンプリング手動制御→OFF //Sample Enable // (例)ASAM = 0(ADC_AUTO_SAMPLING_OFF) の時 SAMP=1(ADC_SAMP_ON)で変換開始 //DONE bit0 : AD変換終了フラグ(AD変換が終了すると1が立つ、 書き込み不可) unsigned int Config2 = //ADCON2レジスタの設定 ADC_VREF_AVDD_AVSS & //VCFG bit13-15=000: S/Hアンプのリファレンス設定: 基準電圧Vdd、シングルエンド //Voltage Reference ADC_SCAN_OFF & //CSCNA bit10=0 : MUX交互自動スキャン制御→オフ //Scan Section ADC_SAMPLES_PER_INT_1 & //SMPI bit2-5 : 割込み頻度→1回毎 //Number of Samples between Interrupts ADC_ALT_BUF_OFF & //BUFM bit1=0: 交互バッファー制御→なし //Buffer mode Select ADC_ALT_INPUT_OFF; //ALTS bit0=0: AD入力の複数バッファーへの格納//Alternate Input sample Mode Select( unsigned int Config3 = //ADCON3レジスタの設定 ADC_SAMPLE_TIME_8 & //SAMC bit8-12 :サンプルホールド時間 → 8サイクル(TAD)//Auto Sample Time bits ADC_CONV_CLK_SYSTEM & //ADRC bit7=0 :AD変換クロック→システムクロック //Conversion Clock Source Select ADC_CONV_CLK_32Tcy; //ADCS bit0-5 :変換クロック数→32Tcy(設定のMAXを選択) //Conversion Clock Select unsigned int ConfigPort = //ADPCFGレジスタの設定 ANLOG/DIGITAl Pin Select //ex1. ENABLE_ALL_ANA ex2. ENABLE_ALL_DIG ex3. ENABLE_AN0_ANA & ENABLE_AN1_ANA ENABLE_AN1_ANA; //AN1 → アナログポート unsigned int ConfigScan = //ADCSSLレジスタの設定 Scan Channel Select SCAN_NONE; //ADCSLL = 0x0000 : 自動スキャン→スキャンせず unsigned int Channel1 = //ADCHSレジスタの設定 ADC_CH0_POS_SAMPLEA_AN1 & //マルチプレクサA(S/Hアンプ)のVref+への接続チャンネル → チャンネル1 ADC_CH0_NEG_SAMPLEA_NVREF; //マルチプレクサA(S/Hアンプ)のVref-への接続チャンネル → Vss unsigned int Count; unsigned int AdcValue; char Buf[17]; //文字列のバッファー用レジスタ int Chanel = 0; //MCP4822 ChanelA 選択 FSFILE* pfile; int N_Write; //書き込み回数戻り値 unsigned int N_Read; //読み出し回数戻り値 int Mode_SD = 0; //0:SDカード書き込みモード 0:SDカード読込モード void delay_ms(unsigned int); void AdcFunc(void); //------------------------------------------- void delay_ms(unsigned int N) //ウェイト関数 { __delay32(Clock/4000*N); } void DAout(unsigned int Out) //DAコンバータ MCP4822への出力関数 { int i =0; LATDbits.LATD9 = 0; // clock low // RD9 : Clock(SCK) LATDbits.LATD8 = 0; // cs low (select) // RD8 : Chip Select(CS) LATDbits.LATD3 = Chanel; // VoutAに出力 0:Chanel A 1:Chanel B // RD3 : Data(SDI) LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low LATDbits.LATD3 = 1; //dumy LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low LATDbits.LATD3 = 0; //ゲイン設定ビット 1: G = 1 0: G = 2 // G = 2; V = Data/4096 * 2.048*2 [V] LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low LATDbits.LATD3 = 1; //シャットダウン設定ビット 1: 出力イネイブル 0: シャットダウン // output enable LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low for(i=0; i<12; i++) // 送信データをMSBから順次1ビットづつ出力する { if((Out & 0b0000100000000000) == 0)LATDbits.LATD3 = 0; else LATDbits.LATD3 = 1; Out = (Out << 1); LATDbits.LATD9 = 1; // clock high LATDbits.LATD9 = 0; // clock low } LATDbits.LATD8 = 1; // cs high (MCP4822 Disable) } void SD_Func(void) // AD変換読み取り & 液晶表示 { float Volt; unsigned int I; unsigned int F; unsigned int Buf_Input[1]; //AD読込みのホールド値&SDカード書き込み値 unsigned int Buf_Output[1]; if(Mode_SD == 0) //SDカードへ書き込み { SetChanADC12(Channel1); //Vref-(RB1、AN1) → GND ADCON1bits.SAMP =1; //サンプリング開始 //サンプルホールド時間:8TAD (ADCON3のSAMC<3:0>) //変換の自動開始 //変換時間:31TAD (ADCON3のADCS<5:0>) while(!ADCON1bits.DONE); //AD変換終了フラグが1になるまでまつ Buf_Input[0] = ADCBUF0; //AD変換値読込み(読込みが早い) //バッファー0の読み出し N_Write = FSfwrite((const void*)Buf_Input,sizeof(unsigned int),1,pfile);//ファイルにデータ書き込み if(N_Write == 1) //正常な場合:書き込み回数が返ってくる { Count++; } else //異常な場合 { lcd_clear(); sprintf(Buf,"Write No%d NG !!",Count); //液晶に"Write NG !" を表示 lcd_str(Buf); return 0; } } else { PORTFbits.RF5 = 0; //CS=0 SDカードのチップセレクトenable N_Read = FSfread(Buf_Output,sizeof(unsigned int),1,pfile);//ファイルからデータ読込み PORTFbits.RF5 = 1; //CS=1 SDカードのチップセレクトdisable if(N_Read != 0) { DAout(Buf_Output[0]); // SDからの出力をMCP4822に出力 } } } void _ISR _T1Interrupt(void) //100Hzの割込み発生 { IFS0bits.T1IF = 0; //IFS0レジスタの T1IF(タイマ1の割込み検出)フラグリセット SD_Func(); // AD変換読み取り & 液晶表示 } /// メイン関数 int main(void) { TRISB = 0b0000000000000010; // AD入力のbit1(AN1 RB1)のみ入力 TRISF = 0; TRISD = 0; //ポートDを出力モードに設定 TRISF = 0; OpenADC12( Config1, //ADCON1レジスタの設定 Config2, //ADCON2レジスタの設定 Config3, //ADCON3レジスタの設定 ConfigPort, //ADPCFGレジスタの設定 ConfigScan //ADCSSLレジスタの設定 ); ///サンプリング周波数 100Hz(10Hz) /// bit15:タイマOn制御ビット bit14:未実装 ビット13 OpenTimer1(T1_ON & //タイマ1ON T1_GATE_OFF & //ゲート制御off T1_PS_1_256 & //プリスケーラ 1/256 T1_SYNC_EXT_OFF & //クロック同期制御OFF T1_SOURCE_INT , //クロック源:内部クロック 80000000/4/100/256 - 1 //サンプリング周波数100Hz // 80000000/4/10/256 - 1 //サンプリング周波数10Hz ); lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); // 全消去 sprintf(Buf,"SD Ver6 !!%u",Count);//arguementがないと遅い C30のバグ? lcd_str(Buf); //液晶表示 delay_ms(2000); ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_ON); //割込みレベル5 タイマ1割込みON EnableIntT1; //割込み許可 PORTFbits.RF5 = 0; //CS=0 SDカードのチップセレクトenable LATDbits.LATD2 = 1; while(!FSInit()); //SDカードイニシャライズ SDカードの実装とフォーマット済をチェック pfile = FSfopen("DATA.DAT","w"); //ファイル書き込みモードでオープン 但しファイルがなければ新規ファイル作成 PORTFbits.RF5 = 1; //CS=1 SDカードのチップセレクトdisable Mode_SD = 0; //SD書き込みモード Count = 0; ConfigIntTimer1(T1_INT_PRIOR_7 & T1_INT_ON); //割込みレベル5 タイマ1割込みON EnableIntT1; //割込み許可 do { }while(Count < 1000); // 50個の符号なし整数(2バイト)データをSDカードに書き込むまで繰り返す PORTFbits.RF5 = 1; //CS=1 SDカードのチップセレクトdisable DisableIntT1; FSfclose(pfile); // ファイルを閉じる PORTFbits.RF5 = 0; //CS=0 SDカードのチップセレクトenable pfile = FSfopen("DATA.DAT","r"); //ファイル読込みモードでオープン Mode_SD = 1; //SDカード読込モード N_Read = 1; //0だとwhile(N_Read !=0)が割込みが入る前に真となりループを抜けてしまう EnableIntT1; //タイマ1割込み許可 do { }while(N_Read !=0); //N_ReaDに0が戻ってくる(EOF)まで待つ FSfclose(pfile); // ファイルを閉じる DisableIntT1; while(1); CloseADC12(); //AD変換終了処理 CloseTimer1(); return 0; }
//************************************************************************** //インクルードファイル 1lcd_lib_C30.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C30コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C30コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C30.h" unsigned int _1usec; // 1μsec待つに必要なウェイト回数 unsigned int _50usec; //50μsec待つに必要なウェイト回数 unsigned long N_msec; // 1msec待つに必要なウェイト回数 //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 __delay32(_1usec); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) __delay32(_1usec); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 __delay32(_50usec); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 __delay32(2*N_msec); // 2msec待ち else __delay32(_50usec); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 // __delay32(15*N_msec); //15msecウェイト } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { _1usec =(unsigned int)( Clock / 4000000); // 1μsecに要するウェイト回数 //__delay32(N) : Nが11以下の場合でも11回ウェイト _50usec = (unsigned int)(Clock / 4000000 * 50); //50μescに要するウェイト回数 N_msec = (unsigned long int)(Clock / 4000); // 1msecに要するウェイト回数 // = Clock / 4000000*1000 __delay32(20*N_msec); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set __delay32(5*N_msec); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set __delay32(N_msec); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set __delay32(N_msec); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set __delay32(N_msec); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home } ************************************************************************************************* ************************************************************************************************* *** *** *** その他のインクルードファイルは *** *** 「C言語ではじめるPIC24F活用ガイドブック」(後閑哲也 著 技術評論社) *** *** の付属CDに収納されています。 *** ************************************************************************************************* ************************************************************************************************* //************************************************************************************************ //************************************************************************************************ //以下は インクルードファイル SD-SPI.hの中で変更部位のみを抜粋したものです。 ピンアサイン関係の 変更です。 // … … /********************************************************************/ /* Pin and register definitions */ /********************************************************************/ #define SD_CS PORTFbits.RF5 #define SD_CS_TRIS TRISFbits.TRISF5 #define SD_CD PORTDbits.RD0 #define SD_CD_TRIS TRISDbits.TRISD0 #define SD_WE PORTDbits.RD1 #define SD_WE_TRIS TRISDbits.TRISD1 // Registers for the SPI module you want to use #define SPICON1 SPI1CON #define SPISTAT SPI1STAT #define SPIBUF SPI1BUF #define SPISTAT_RBF SPI1STATbits.SPIRBF #define SPICON1bits SPI1CONbits #define SPISTATbits SPI1STATbits // Tris pins for SCK/SDI/SDO lines #define SPICLOCK TRISFbits.TRISF6 #define SPIIN TRISFbits.TRISF2 #define SPIOUT TRISFbits.TRISF3 … … //************************************************************************************************ //************************************************************************************************ // 以下は インクルードファイル SD-SPI.cの中で修正した部分のみを抜粋したものです。 // SDカードのソケットにより書き込みプロテクトの論理が異なるものがあるようです。 // (後閑さんにおしえていただきました)
// わたしが使用したSDカードソケットはサンハヤト鰍フCK29です。CK29のライトプロテクトWEの論理は // ”ライトプロテクトが書き込み可能な位置にあるSDカードを奥まで挿入すると ON ”です。すなわち // 以下の場合 SDカードのWEはOFFです。 // ・SDカードが挿入されていない場合 // ・ライトプロテクトが書き込み不可の位置にあるSDカードが奥まで挿入されている場合
//
// 以下は修正前のソースコードです。SDカードの検出チェックの部分です。修正したものは SD_WEの // 前の”!”が削除されています。 // // BYTE // WriteProtectState(void)
// {
// return(!SD_WE); // 修正後は”!”が削除されています。
// }
// // // // 以下は修正後のソースコードです。 BYTE WriteProtectState(void)
{
return(SD_WE); // ”!”が削除されています。
}
// 以下はFSconfig.hファイルの中で変更した部分のみを記載しています。システムクロックを20MHzから80MHzに変更
//したことに伴う変更です
// Define the system clock speed
//#define SYSTEM_CLOCK (DWORD)20000000
#define SYSTEM_CLOCK (DWORD)80000000
<動作結果>
外部発振器からの三角波(1Hz Vp-p:0-4V)をSDカードに読み込んだ後、再生してDAコンバータに出力した波形です。
サンプリング周波数が100Hzの場合と10Hzの場合を示します。
尚、サンプルプログラムはサンプリング周波数が100Hzの場合のものです。
ADコンバータ入力電圧 (dsPIC30F4013のRB1ピン) |
DAコンバータ出力電圧 (MCP4822の8ピン) |
|||
サンプリング周波数:100Hz | サンプリング周波数:10Hz | |||
(外部発振器: ファンクションジェネレータ(INSTEC SFG-2104) 波形観測:デジタルオシロ 岩通 DS-5102)
(1) PIC24FJ64GA002 編
PIC24FJ64GA002を使用した、WAVファイル形式録音機能付きMP3プレーヤーを紹介します。MP3のデコーダーICとしてはVS1011Eを
使用しています。 VS1011Eのライブラリ関数(VS1011.h、VS1011.c)は後閑哲也さんが設計されたものです。後閑さんには本プレーヤー製作に
あたり貴重なアドバイスを多々いただきました。
★ mp3デコーダーIC VS1011Eは QFPがキバンにハンダ付けされ、端子が2.54インチのピンヘッダーコネクタに変換されたもの(700円/個)が
秋月電子で販売されています。私はこれをつかって試作品を製作しました。
<試作品の仕様>
・再生モードと録音モードを有すること。再生、録音のモード切替はモメンタリースイッチでおこなうこと
・mp3ファイルについては再生のみとし、エンコード機能はつけない
・mp3、wav形式でSDカードに収録されている音楽・音声データを再生できること
・mp3ファイルのデコーダICとして、VS1011Eを使用すること
・再生はSDカード内にある音楽・音声データを順番におこなう。但し、スキップボタンをもうけ再生データをスキップできるようにすること
・録音は、マイクレベルの音声信号を増幅しPICでAD変換して、データはSDカードにWAV形式のファイルとしてファイルすること
・録音するWAVファイルの諸元は下記とする
@圧縮のフォーマットID …… リニアPCM
Aチャンネル数 …… モノラル
Bサンプリングレート……22050 Hz
Cデータ転送速度 ……44100 バイト/sec
DBlock align …… 2 バイト/サンプル
E量子化ビット数……16ビット
・録音するファイル名はVOICE.wavとする。SDカード内のルートにこのファイル名のファイルが存在しない場合はファイルをつくること。 また、
すでにVOICE.wavが存在する場合は上書きするものとする。
・キャラクタ液晶により、録音/再生時のファイル名を表示する。
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> /* wavファイル録音付きMP3プレーヤ PIC24FJ64GA002+VS1011e,SDカード Ver.2 //バグ修正 //・WAVファイル生成安定化 //・スキップ操作における選択ファイル順序玉成 他 */ #include <p24FJ64GA002.h> #include "GenericTypeDefs.h" #include "FSIO.h" #include "VS1011.h" #include <uart.h> #include <timer.h> #define STX 0x02 //STX #define ETX 0x03 //ETX /// コンフィギュレーション ビットの設定 _CONFIG1 ( JTAGEN_OFF & //JTAGポート: OFF GCP_OFF & //コードプロテクト: OFF GWRP_OFF & //書き込みプロテクト: OFF BKBUG_OFF & //バックグランドデバック: OFF COE_OFF & //クリップオン エミュレーション: OFF ICS_PGx1& //ICDピンの選択: EMUC/EMUDをPGC1/PGD1と共用 FWDTEN_OFF //ウォッチドックタイマ: OFF ) _CONFIG2 ( IESO_OFF & // 2速度スタートアップ機能:OFF FNOSC_FRCPLL & //内臓高速RC発振(8MHZ)回路 + 4倍PLL → 32MHz(= 8MHz × 4) FCKSM_CSDCMD & //クロック切替え制御:OFF クロックモニタ:OFF OSCIOFNC_OFF & //OSCO/RC15 function: OSCO or Fosc/2 IOL1WAY_OFF & //RP Register Protection: Unlimited Writes To RP Registers I2C1SEL_PRI & //I2C1 pins Select: Use Primary I2C1 pins POSCMOD_NONE //発振回路モード Oscillator Selection: Primary disabled ) struct myWaveHeader //全ヘッダサイズ: 44バイト { char id_RIFF[4]; //Chunk ID RIFFヘッダ // 4バイト unsigned long int size_file; //ファイルサイズ(総ファイルサイズ - 8)バイト //4バイト char id_WAVE[4]; //Chunk ID WAVE //4バイト char id_fmt[4]; //Chunk ID fmt //4バイト unsigned long int size_fmt; //フォーマット関連定義データのサイズ //4バイト unsigned int code_wavefmt; //WAVEファイルの圧縮フォーマットコード 但し、リニアPCMは圧縮なし//2バイト unsigned int channel; //チャンネル数 //2バイト unsigned long int rate_sample; //サンプリングレート //4バイト unsigned long int rate_tranfer; //転送速度[byte/sec] //4バイト unsigned int align_block; //サンプルあたりのバイト数[byte/サンプル] //2バイト unsigned int bit_sample; //量子化ビット数[bit] //2バイト char id_data[4]; //Chunk ID data //4バイト unsigned long int size_data; //サンプリングデータのサイズ[byte] //4バイト } ; struct myWaveHeader mywaveheader = // WAVEファイルヘッダ構造体の初期化 //44バイト { "RIFF", //Chunk ID RIFF // 4バイト 0x0006C28C, //(仮)ファイルサイズ: 443020バイト //特に値に意味なし "WAVE", //Chunk ID WAVE //4バイト "fmt ", //char id_fmt[4]; //Chunk ID fmt //4バイト 16, //16バイト at リニアPCM フォーマット関連定義データのサイズ //4バイト 0x0001, //WAVEファイルの圧縮フォーマットコード: リニアPCM //2バイト 1, //チャンネル数: モノラル //2バイト 22050, //サンプリングレート: 22.05[Hz] //4バイト 44100, //転送速度: 44100[byte/sec] //4バイト //サンプリングレート: 22.05[Hz] 2, //サンプルあたりのバイト数: 2[byte]/サンプル //2バイト 16, //量子化ビット数: 16[bit] //2バイト "data", //Chunk ID data //4バイト 0x0006C267 ////(仮)サンプリングデータのサイズ: 442983バイト //特に値に意味なし }; struct myWaveHeader* ptrWH; //構造体のポインタ Clock = 320000000; // FSFILE *fptr,*fptr2; //FATファイル用構造体のポインタ変数 size_t result; BYTE Buffer[256]; SearchRec Record; SearchRec *rptr = &Record; BYTE Volume, ChgFlag, BASS; // MP3用変数 int Mode = 0; //録音/再生モード 0:再生 1:録音 unsigned long int adr_SD; unsigned long int count_block = 0; //SD送信ブロック(512バイト)数 unsigned int size_dataBlock = 512; int count_buf1 = 0; //バッファ1データ数 int count_buf2 = 0; //バッファ2データ数 int flag_buf1 = 0; //音声データバッファ1の状態 int flag_buf2 = 0; //音声データバッファ2の状態 // 0:音声データ受信可能状態 1:SDへ音声データ送信可能状態 int mode_tranceive = 0; //送受信モード //0: バッファ1=音声タ受信、バッファ2=SD送信 //1: バッファ1=SD送信モード、バッファ2=音声受信 int data1_sound[512]; //音声データバッファ1 int data2_sound[512]; //音声データバッファ2 int ix = 0,iy = 0; char* str_filename; int Stop_SDwriting = 0;// 1: SDカードへの書込み停止 0: 書込み許可 int Next = 0; void my_delay_ms(unsigned int N) //1msec のディレー関数 { __delay32(Clock/2000*N); //システムクロック周波数2000000HzのPICの1サイクルディレー時間=1μsec } // → Clock(Hz)/2000 = 1000μsec = 1msec void wav_end(void) //録音ファイル完成処理 { unsigned int result; int count_N; mywaveheader.size_data = count_block * 1024 ; //[バイト] mywaveheader.size_file = count_block * 1024 + sizeof mywaveheader - 8; //[バイト] count_N = 0; do{ delay_ms(100); result = FSfseek(fptr,0,SEEK_SET); //ファイルの先頭にファイルポインタの位置を移動 putcUART1('\r'); // ¥r: 液晶画面をクリア& 文字表示位置を一行目の先頭へ移動 printf("fseek N=%d ",count_N); putcUART1('\n'); // ¥n: 文字表示位置を2行目の先頭へ printf("result=%d ",result); //文字データを送信 putcUART1(STX); // 液晶画面表示 count_N++; }while(result != 0); delay_ms(1500); count_N = 0; do{ delay_ms(100); result = FSfwrite((const void*)ptrWH,sizeof(struct myWaveHeader),1,fptr); //ファイルにヘッダー情報書き込み putcUART1('\r'); // ¥r: 液晶画面をクリア& 文字表示位置を一行目の先頭へ移動 printf("blk=%lu N=%d ",count_block,count_N); putcUART1('\n'); // ¥n: 文字表示位置を2行目の先頭へ printf("result=%d ",result); //文字データを送信 putcUART1(STX); // 液晶画面表示 count_N++; }while(result != 1); delay_ms(1500); count_N = 0; do{ delay_ms(100); result = FSfclose(fptr); // ファイルを閉じる putcUART1('\r'); // ¥r: 液晶画面をクリア& 文字表示位置を一行目の先頭へ移動 printf("fclose N=%d ",count_N); putcUART1('\n'); // ¥n: 文字表示位置を2行目の先頭へ printf("result=%d ",result); //文字データを送信 putcUART1(STX); // 液晶画面表示 count_N++; }while(result != 0); delay_ms(1500); } void playmode_LCD() //液晶表示 { putcUART1('\r'); // ¥r: 液晶画面をクリア& 文字表示位置を一行目の先頭へ移動 printf("%s ",str_filename); putcUART1('\n'); // ¥n: 文字表示位置を2行目の先頭へ printf("Play Mode "); //文字データを送信 putcUART1(STX); // 液晶画面表示 } void play() // 音楽データの出力 { int i; ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_OFF); //タイマ1割込み禁止 DisableIntT1; if(fptr != 0) // 正常にオープンできたか? { do{ // ファイルのEOFまで音声データ連続出力 SRbits.IPL = 7; // SPI処理中は割り込み禁止 MP3_XDCS_IO = 0; //#define MP3_XDCS_IO LATBbits.LATB15=0 → DREQ=0 result = FSfread(Buffer, 1, 256, fptr); //SDカードのデータを256バイト単位で読み出し for(i= 0; i<result; i++) // 読み出したバイト数だけ繰り返し { SendData(Buffer[i]); // 音楽データ送信 } SRbits.IPL = 2; // 割り込み再許可 if(Mode == 1)return; //録音モードなら 再生は終了 if(Next == 1)result = 0; } while(result != 0); // ファイルのEOFまで継続 Next = 0; MP3_XDCS_IO = 1; // 再生完了処理 FSfclose(fptr); // ファイルのクローズ PlayEnd(); // 再生終了処理 result = FindNext(rptr); // 連続再生のため次のファイルへ if((result != 0) || (Record.attributes != ATTR_ARCHIVE)) FindFirst("*.*", ATTR_ARCHIVE, rptr); // ファイルの終わりなら再度最初から繰り返し fptr = FSfopen(Record.filename, "r"); str_filename = Record.filename; SRbits.IPL = 2; // 割り込み再許可 playmode_LCD(); } } void SD_write() { if(mode_tranceive == 0) //バッファ2=SD送信、バッファ1=音声受信モード { if(flag_buf2 == 1) //バッファ2がSDへ送信可能状態の場合・バッファ1は音声受信可能状態 { FSfwrite((const void*)data1_sound,sizeof(int),size_dataBlock,fptr);//SDカードにデータ書き込み count_block++; flag_buf2 = 0; //→ バッファ2送信完了、受信可能状態 } } else //バッファ1=SDへ送信可、バッファ2=音声受信モード { if(flag_buf1 == 1) //バッファ1がSDへ送信可能状態の場合・バッファ2は音声受信可能状態 { FSfwrite((const void*)data2_sound,sizeof(int),size_dataBlock,fptr);//SDカードにデータ書き込み count_block++; flag_buf1 = 0; //→ バッファ1送信完了、受信可能状態 } } if(Stop_SDwriting == 1) // { delay_ms(200); wav_end(); //録音wavファイル終了処理 Mode = 0; //音楽再生モードへ delay_ms(1000); fptr = FSfopen("VOICE.WAV", "r"); // ファイルのオープン putcUART1('\r'); // ¥r: 液晶画面をクリア& 文字表示位置を一行目の先頭へ移動 printf("VOICE.WAV "); putcUART1('\n'); // ¥n: 文字表示位置を2行目の先頭へ printf("Play Mode "); //文字データを送信 putcUART1(STX); // 液晶画面表示 } } void _ISR _T1Interrupt(void) //タイマ1割込み、ADコンバータ読み込み、SDカード書き込み { unsigned int temp1; long int temp2; IFS0bits.T1IF = 0; //フラグクリア AD1CON1bits.SAMP =1; //サンプリング開始 while(!AD1CON1bits.DONE); //AD変換終了フラグがたつ(1になるまで)待つ temp1 = ADC1BUF0; //ADC1のAN1のバッファーからAD変換結果を読込む temp2 = temp1*64 - 32768; //32768 = 64*1024 / 2; //無音基準レベル:32768( = unsigned int / 2) if(temp2 >= 32767) temp2 = 32767; //音声レベルクリップ if(temp2 <= -32768)temp2 = -32768; //送信優先: 未送信データがバッファに残っている場合は入力する音声データは無視する if(mode_tranceive == 0) //バッファ1=音声受信、バッファ2=SD送信 { if(flag_buf1 == 0) //バッファ1が受信可能状態なら { data1_sound[count_buf1] = temp2; //受信データをバッファ構造体1のdata_sound[ ]に保存 count_buf1++; if(count_buf1 >= size_dataBlock) { count_buf1 = 0; flag_buf1 = 1; //→ バッファ1: 音声データフル・SD転送待ち mode_tranceive = 1; } } //バッファ1にまだ未送信音声データが残っていた場合は、音声データは受信しない } else //バッファ2=音声受信、バッファ1=SD送信 { if(flag_buf2 == 0) //バッファ2が受信可能状態なら { data2_sound[count_buf2] = temp2; //受信データをバッファ構造体2のdata_sound[ ]に保存 count_buf2++; if(count_buf2 >= size_dataBlock) { count_buf2 = 0; flag_buf2 = 1; //→ バッファ2:音声データフル・SD転送待ち mode_tranceive = 0; } } } //バッファ2にまだ未送信音声データが残っていた場合は、音声データは受信しない } void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void) // スイッチ 変化割りこみ { if(!PORTAbits.RA4) //再生/録音ボタンがクリックされた場合 { if(Mode == 0) //再生モードの場合 { Mode = 1; //録音モードへ Stop_SDwriting = 0; //SDカードへの書き込み許可 MP3_XDCS_IO = 1; //VS1011E 音データ信号ラインOFF MP3_XCS_IO = 1; //VS1011E チップセレクト解除 FSfclose(fptr); // 現在のファイルを強制クローズ PlayEnd(); // 再生終了処理 delay_ms(200); fptr = FSfopen("VOICE.wav","w"); //ファイル上書き込みモードでオープン 但しファイルがなければ新規ファイル作成 ptrWH = &mywaveheader; //構造体にmywaveheaderの先頭アドレス設定 FSfseek(fptr,0,SEEK_SET); //ファイルの先頭にファイルポインタの位置を移動 delay_ms(50); FSfwrite((const void*)ptrWH,sizeof(struct myWaveHeader),1,fptr); //ファイルにヘッダー情報書き込み delay_ms(50); adr_SD = 0x2C; //ファイルの先頭から0x2C(44)バイト(音声データ書き込み開始オフセット)のところにに FSfseek(fptr,adr_SD,SEEK_SET);//ファイルポインタの位置を移動 count_block = 0; //SDカードに512バイト単位で書き込んだ回数をリセット putcUART1('\r'); // ¥r: 液晶画面をクリア& 文字表示位置を一行目の先頭へ移動 printf("VOICE.wav "); putcUART1('\n'); // ¥n: 文字表示位置を2行目の先頭へ printf("Record Mode "); //文字データを送信 putcUART1(STX); // 液晶画面表示 delay_ms(300); //LATBbits.LATB3 = 1; //LED 消灯 ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_ON); //割込みレベル0 タイマ1割込みON EnableIntT1; //割込み許可 } if((Mode == 1) && (count_block >= 10)) //録音モード かつ 10ブロック以上書き込んでいるななら(チャタリング防止) { ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_OFF); //タイマ1: 割り込み優先レベル5 // IPC0bits.T1IP = 5; DisableIntT1; //タイマ1: 割り込み禁止 //IEC0bits.T1IE = 0; Stop_SDwriting = 1; //SDカード書込み終了 //1ブロック書込み後終了処理開始 //★ここですぐ終了処理を行わないこと!! } } if(!PORTAbits.RA2) //スキップボタンがクリックされた場合 { Next = 1; //再生中のファイルのセクタ読み込み終了後、次の曲を再生 } IFS1bits.CNIF = 0; // 変化割り込みフラグクリア } int main(void) { CLKDIV = 0; // クロック1/1 TRISA = 0b0000000000011110; //RA1-4は入力、その他出力 TRISB = 0b0100011100000100; //入力:RA2-3,RB3:out 8-10,14 他:出力 //AD1CON1レジスタの設定 AD1CON1bits.ADON = 1; //A/Dコンバータモジュール有効 AD1CON1bits.ADSIDL = 0; //アイドルモード中もモジュール動作継続 AD1CON1bits.FORM1 = 0; //AD1CON1bits.FORM0 と2ビットでセット AD1CON1bits.FORM0 = 0; //00: 符号なし整数 (参考)11:符号なし固定少数、10:固定少数、01:整数 //★ Michrochip PIC24FJ64GA002のデータシートでは00がIntegerとなっているがUnsigned Integerの誤植である。 AD1CON1bits.SSRC2 = 1; //AD1CON1bits.SSRC2-AD1CON1bits.SSRC0 でセット AD1CON1bits.SSRC1 = 1; //111: 内蔵カウンタでサンプリングを終了させ変換を開始する AD1CON1bits.SSRC0 = 1; //(参考)000: SAMPビットでサンプリングを終了し変換を開始する AD1CON1bits.ASAM = 0; //SAMPビットのセットでサンプリングを開始する。 (参考)1: 自動開始(前の変換終了後すぐサンプリングを開始する) AD1CON1bits.SAMP = 0; //サンプリング停止 //AD1CON2レジスタの設定 AD1CON2bits.VCFG2 = 0; //AD1CON2bits.VCFG2 - AD1CON2bits.VCFG0(VCFG<2:0>)の3ビットでセット AD1CON2bits.VCFG1 = 0; //000:リファレンス電圧 → Vdd -Vss AD1CON2bits.VCFG0 = 0; //(参考)001:リファレンス電圧 → 外部入力 - Vss 他 AD1CON2bits.CSCNA = 1; //マルチプレクサMUXAでのスキャン: する AD1CON2bits.SMPI3 = 0; //AD1CON2bits.SMPI3 - AD1CON2bits.SMPI0(SMPI<3:0>)の4ビットでセット AD1CON2bits.SMPI2 = 0; //0000: AD変換完了毎の割り込み発生(割り込み有効の場合) AD1CON2bits.SMPI1 = 0; //(参考)0011: 4サンプルのAD変換終了後 割り込み発生(割り込み有効の場合) AD1CON2bits.SMPI0 = 0; // AD1CON2bits.BUFM = 0; //バッファーを1個の16ワードバッファとする。 (参考)1: 2組の8ワードバッファーとする AD1CON2bits.ALTS = 0; //常にMUXAを入力マルチプレクサにする (参考)1: MUXA,MUXBを交互につかう //AD1CON3レジスタの設定 AD1CON3bits.ADRC = 0; //AD変換クロック源:システムクロック (参考)1: A/D内臓RCクロック AD1CON3bits.SAMC4 = 1; //AD1CON3bits.SAMC4 - AD1CON3bits.SAMC0(SAMC<4:0>)の5ビットでセット AD1CON3bits.SAMC3 = 1; //アクイジションタイム(Tad(クロック周期)×N)設定 AD1CON3bits.SAMC2 = 1; //1111: 31Tad AD1CON3bits.SAMC1 = 1; //(参考)0001: 1Tad 0010: 2Tad 0011: 3Tad ・・・・ AD1CON3bits.SAMC0 = 1; // AD1CON3bits.ADCS7 = 0; //AD1CON3bits.ADCS7 - AD1CON3bits.ADCS0(ADCS<7:0>)の8ビットでセット AD1CON3bits.ADCS6 = 0; //AD変換のクロックとクロック源の関係 AD1CON3bits.ADCS5 = 0; //0000 0101: 1Tad = 5Tcy AD1CON3bits.ADCS4 = 0; //(参考) 0000 0000: 1Tad = 0.5Tcy AD1CON3bits.ADCS3 = 0; // 0000 0001: 1Tad = 1.0Tcy AD1CON3bits.ADCS2 = 1; // 0000 0010: 1Tad = 1.5Tcy AD1CON3bits.ADCS1 = 0; // ・・・・ AD1CON3bits.ADCS0 = 1; // 1111 1111: 1Tad = 128Tcy //AD1CHSレジスタの設定 AD1CHSbits.CH0NB = 0; //マルチプレクサMUXB用負側入力選択ビット: VR- (参考)1: AN1 AD1CHSbits.CH0SB3 = 0; //AD1CHSbits.CH0SB3 - AD1CHSBbits.CH0SB0(<CH0SB<3:0>)の4ビットでセット AD1CHSbits.CH0SB2 = 0; //マルチプレクサMUXBの正側入力選択 AD1CHSbits.CH0SB1 = 0; //0000: AN0 AD1CHSbits.CH0SB0 = 0; //(参考)0001: AN1 0011 AN2 .... 1111: AN15 AD1CHSbits.CH0NA = 0; //マルチプレクサMUXA用負側入力選択ビット: VR- (参考)1: AN1 AD1CHSbits.CH0SA3 = 0; //AD1CHSbits.CH0SA3 - AD1CHSbits.CH0SA0(<CH0SA<3:0>)の4ビットでセット AD1CHSbits.CH0SA2 = 0; //マルチプレクサMUXAの正側入力選択 AD1CHSbits.CH0SA1 = 0; //0000: AN0 AD1CHSbits.CH0SA0 = 0; //(参考)0001: AN1 0011 AN2 .... 1111: AN15 //AD1PCFGレジスタの設定 // ★デバイスリセットでは全ビット0となるためデフォルトではアナログ入力となるのでデジタルで使う多重ピンは、コンフィグレーションでデジタル設定が必要!! //PIC24FJ64GA002にはないピン・設定も特に必要ないが設定 AD1PCFGbits.PCFG15 = 1;//RA15/AN15アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ // AD1PCFGbits.PCFG14 = 1;//RA14/AN14アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ // AD1PCFGbits.PCFG13 = 1;//RA13/AN13アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG12 = 1;//RA12/AN12アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG11 = 1;//RA11/AN11アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG10 = 1;//RA10/AN10アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG9 = 1;//RA9/AN9アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ // AD1PCFGbits.PCFG8 = 1;//RA8/AN8アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ // AD1PCFGbits.PCFG7 = 1;//RA7/AN7アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ // AD1PCFGbits.PCFG6 = 1;//RA6/AN6アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG5 = 1;//RA5/AN5アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG4 = 1;//RA4/AN4アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG3 = 1;//RA3/AN3アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG2 = 1;//RA2/AN2アナログ入力orデジタル入力選択: デジタル (参考)0: アナログ AD1PCFGbits.PCFG1 = 0;//RA1/AN1アナログ入力orデジタル入力選択: アナログ (参考)0: アナログ ★AN1のみアナログ入力 AD1PCFGbits.PCFG0 = 1;//RA0/AN0アナログ入力orデジタル入力選択: デジタル (参考)0: デジタル // AD1CSSLレジスタの設定 //読み込むチャンネル(入力端子)をセットする AD1CSSLbits.CSSL15 = 0; //AN15をMUXAでスキャンしない (参考)1: スキャンする // AD1CSSLbits.CSSL14 = 0; //AN15をMUXAでスキャンしない (参考)1: スキャンする // AD1CSSLbits.CSSL13 = 0; //AN13をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL12 = 0; //AN12をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL11 = 0; //AN11をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL10 = 0; //AN10をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL9 = 0; //AN9をMUXAでスキャンしない (参考)1: スキャンする // AD1CSSLbits.CSSL8 = 0; //AN8をMUXAでスキャンしない (参考)1: スキャンする // AD1CSSLbits.CSSL7 = 0; //AN7をMUXAでスキャンしない (参考)1: スキャンする // AD1CSSLbits.CSSL6 = 0; //AN6をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL5 = 0; //AN5をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL4 = 0; //AN4をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL3 = 0; //AN3をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL2 = 0; //AN2をMUXAでスキャンしない (参考)1: スキャンする AD1CSSLbits.CSSL1 = 1; //AN1をMUXAでスキャンしない (参考)1: スキャンする ★AN1のチャンネルだけ読み込む AD1CSSLbits.CSSL0 = 0; //AN0をMUXAでスキャンする (参考)0: スキャンしない /// インターバルタイマ1 周期 45.3μsec (音データサンプリング周期) OpenTimer1 ( T1_ON & //タイマ1ON T1_GATE_OFF & //ゲート制御ON T1_PS_1_1 & //プリスケーラ 1/1 1/8 1/64 1/256 T1_SYNC_EXT_OFF & //クロック同期制御OFF T1_SOURCE_INT, //クロック源:内部クロック 724 //サンプリング周波数 22.05KHz // 362 //サンプリング周波数 44.1KHz //SPI転送速度(現:1Mbps)アップ、アルゴリズム見直し等が必要 // → 22.68×(32MHz/2MHz)=362.88 → 363 ); //PR1 = 363 - 1 = 362 CNPU1 = 0b0000000000000001; //CN0(RA4),CN7(RB3) プルアップするポート CNPU2 = 0b0100000011100001; //CN16(RB10),CN21(RB9),CN22(RB8),CN23(RB7),CN29(RA3),CN30(RA2) プルアップするポート CNEN1 = 0b0000000000000001; //CN0(RA4) 変化割り込みを許可するポート CNEN2 = 0b0100000000000000; //CN30(RA2)の 変化割り込みを許可//何故かRA3(ピン10)を変化割込み許可すると音がでない IPC4bits.CNIP = 6; //変化割り込み優先レベル:6 //タイマ1割込み(優先レベル5)より高優先割り込みに設定 IEC1bits.CNIE = 1; //変化割込み:割り込み許可 // SPIのピン割り付け RPINR20bits.SDI1R = 7; // SDI1をRP7に RPOR3bits.RP6R = 8; // SCK1をRP6に RPOR2bits.RP5R = 7; // SDO1をRP5に RPINR22bits.SDI2R = 10; // SDI2をRP15に RPOR6bits.RP12R = 11; // SCK2をRP13に RPOR5bits.RP11R = 10; // SDO2をRP14に /// 液晶表示用、 UART1初期設定 19200bps 8ビット パリティなし、フロー制御なし RPOR0bits.RP0R = 3; // UART1ピン割付 リマッピング UART1 TX to RP0(RB0 ピン4番) U1BRG = 52; // 19200bps at システムクロック32MHz //U1BRG = (Fosc(Hz)/2/16/baud(bps) - 1 // = 32000000/2/16/19200 - 1 = 52.08 → 52 U1MODE = 0b1000100000000000; // UART1初期設定 U1STA = 0b0000010000000000; // UART1初期設定 LATBbits.LATB4 = 0; //CS = 0; VS1011_Init(); // VS1011eの初期化 Volume = 0x08; // 音量の初期設定 SetVolume(Volume, Volume); BASS = 0; // バスブーストの初期設定 SetBassBoost(BASS,15); delay_ms(1000); while(!FSInit()); // FATの初期化 result = FindFirst("*.*", ATTR_ARCHIVE, rptr); //最初のファイルのサーチ(ルートだけにMP3ファイルがあることが前提) if(result == 0) { fptr = FSfopen(Record.filename, "r"); // ファイルのオープン str_filename = Record.filename; } Mode = 0; playmode_LCD(); LATBbits.LATB3 = 1; //LED 消灯 while(1) { if(Mode == 0)play(); //再生モード else SD_write(); //録音モード } } //---------------------------------------------------------------------------------------------------------- //VS1011.h、VS1011.cは 後閑哲也さんが設計されたファイルです /********************************************************************* * VS1011E用ヘッダファイル : VS1011.h * ********************************************************************/ #include "GenericTypeDefs.h" /** Delay関数用クロック周波数定義 **/ #define CLOCK 16 // MHz /** ポートの定義 */ #define MP3_DREQ_TRIS (TRISBbits.TRISB14) // Data Request #define MP3_DREQ_IO (PORTBbits.RB14) #define MP3_XRESET_TRIS (TRISAbits.TRISA0) // Reset, active low #define MP3_XRESET_IO (LATAbits.LATA0) #define MP3_XDCS_TRIS (TRISBbits.TRISB15) // Data Chip Select #define MP3_XDCS_IO (LATBbits.LATB15) #define MP3_XCS_TRIS (TRISBbits.TRISB13) // Control Chip Select #define MP3_XCS_IO (LATBbits.LATB13) /* SPIはSPI2を使用 */ #define MP3_SCK_TRIS (TRISBbits.TRISB12) #define MP3_SDI_TRIS (TRISBbits.TRISB10) #define MP3_SDO_TRIS (TRISBbits.TRISB11) #define MP3_SPI_IF (IFS2bits.SPI2IF) #define MP3_SSPBUF (SPI2BUF) #define MP3_SPICON1 (SPI2CON1) #define MP3_SPICON1bits (SPI2CON1bits) #define MP3_SPICON2 (SPI2CON2) #define MP3_SPISTAT (SPI2STAT) #define MP3_SPISTATbits (SPI2STATbits) /* 関数プロトタイピング */ BYTE WriteSPI(BYTE output); void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData); void SendData(BYTE Data); void delay_ms(int msec); void VS1011_Init(void); void VS1011_SineTest(void); void SetVolume(BYTE right, BYTE left); void SetBassBoost(BYTE bass, BYTE gfreq); void PlayEnd(void); //--------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------- //VS1011.h、VS1011.cは 後閑哲也さんが設計されたファイルです /***************************************************** * VS1011E 制御ライブラリ : VS1011.c * ******************************************************/ #include "VS1011.h" #include <p24FJ64GA002.h> /************************************ * SPI Read after Write 基本関数 ************************************/ BYTE WriteSPI(BYTE output){ MP3_SPI_IF = 0; // 割り込みフラグクリア MP3_SSPBUF = output; // SPI出力 while(!MP3_SPI_IF); // 入力待ち return MP3_SSPBUF; // 入力データ戻り値 } /************************************ * VS1011用コマンド出力関数 ************************************/ void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData){ MP3_XDCS_IO = 1; // データモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // コマンドモード設定 WriteSPI(0x02); // 書き込み動作指定 WriteSPI(RegAdrs); // レジスタアドレス出力 WriteSPI(UpData); // 上位バイト出力 WriteSPI(LowData); // 下位バイト出力 MP3_XCS_IO = 1; // コマンドモード解除 } /************************************ * VS1011用コマンド出力関数(確認付き) ************************************/ void CmdCheck(BYTE RegAdrs, BYTE UpData, BYTE LowData){ BYTE b1,b2; do{ MP3_XDCS_IO = 1; // データモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // コマンドモード設定 WriteSPI(0x02); // 書き込み動作指定 WriteSPI(RegAdrs); // レジスタアドレス出力 WriteSPI(UpData); // 上位バイト出力 WriteSPI(LowData); // 下位バイト出力 MP3_XCS_IO = 1; // コマンドモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // 読み込み確認 WriteSPI(0x03); // 読み込み動作 WriteSPI(RegAdrs); // レジスタアドレス指定 b1 = WriteSPI(0xFF); // return UpData b2 = WriteSPI(0xFF); // return LowData MP3_XCS_IO = 1; }while((b1 != UpData) || (b2 != LowData)); } /************************************ * VS1011用データ出力関数 ************************************/ void SendData(BYTE Data){ while(!MP3_DREQ_IO); // レディー待ち WriteSPI(Data); } /*********************************************** * 音量レベル設定関数 * vRight = 右チャネル用音量 * vLeft = 左チャネル用音量 * いすれも 0x00=Max 0dB 0.5dBステップで下がる ************************************************/ void SetVolume(BYTE vRight, BYTE vLeft){ Command(0x0B, vRight, vLeft); } /********************************************** * 低音ブースト設定制御関数 * bass: 低音ゲイン レンジは0dBから15dBの範囲 * gfreq: 低音ブースト周波数設定 10Hzステップ 0〜15の範囲 ***********************************************/ void SetBassBoost(BYTE bass, BYTE gfreq) { BYTE temp1 = 0; /* 設定範囲の制限 */ if(bass > 15) bass = 15; if(gfreq > 15) gfreq = 15; /* 8ビットに合成 */ temp1 = gfreq; temp1 |= (bass << 4); Command(0x02, 0xFF, temp1); // BASS return; } /********************************************* * 再生終了処理関数 * *********************************************/ void PlayEnd(void){ int i; /* 再生バッファクリアのため2048バイト送信 */ MP3_XDCS_IO = 0; // XDCSオン for(i=0; i<2048; i++) SendData(0); // 0のデータ連続送信 MP3_XDCS_IO = 1; // XDCSオフ /*** ソフトウェアリセットで完了 **/ Command(0x00, 0x08, 0x24); // SM_RESET送信 while(!MP3_DREQ_IO); // コマンド完了待ち } /******************************************** * VS1011 初期化関数 * VS1011転送モード、SDIテストモード に設定 * VS1011と正常に通信できないと永久待ちとなる *********************************************/ void VS1011_Init(void){ unsigned int val; /***** VS1011用ポートの初期設定 ***/ MP3_XDCS_IO = 1; // DCSをHigh MP3_XCS_IO = 1; // XCSをHigh MP3_XRESET_IO = 0; // XRESETをLow MP3_XRESET_TRIS = 0; // 出力TRIS有効化 MP3_DREQ_TRIS = 1; // DREQ入力モードに MP3_XDCS_TRIS = 0; // XDCS出力///////// MP3_XCS_TRIS = 0; // XCS出力 MP3_SDI_TRIS = 1; // SDI2入力モード MP3_SDO_TRIS = 0; // SDO2出力モード MP3_SCK_TRIS = 0; // SCK2出力モード /***** SPI2の初期設定 ***/ MP3_SPICON1 = 0x003E; // 8ビットモード,CKP = 0,CLK=Fosc/4 (4MHz) // 中央でサンプル(SMP=0) 立上りエッジで送信(CKE=1) MP3_SPICON2 = 0; // フレームモードなし MP3_SPI_IF = 0; // 割り込みフラグクリア MP3_SPISTATbits.SPIEN = 1; // SPI2イネーブル /* RESET解除、VS1011スタート */ delay_ms(50); // 50msec delay MP3_XRESET_IO = 1; // RESET解除 /** モード設定 */ CmdCheck(0x00, 0x08, 0x20); // モード初期設定 新モード、SDIテストモード /* クロックダブラ設定 */ val = 12288 / 2 + 0x8000; // 設定値を求める(データシートより) CmdCheck(0x03, (BYTE)(val /256), (BYTE)val); delay_ms(10); } /******************************************** * VS1011 正弦波テストモード設定関数 * MODEをSPIテストモードに設定しておく必要がある *********************************************/ void VS1011_SineTest(void) { /* テストモードシーケンス出力 */ while(!MP3_DREQ_IO); MP3_XDCS_IO = 0; // Start Sine Test WriteSPI(0x53); WriteSPI(0xEF); WriteSPI(0x6E); WriteSPI(0x7D); // 22.050kHz Out is 5kHz WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); MP3_XDCS_IO = 1; } /**************************** * usec単位ディレイ関数 ****************************/ void delay_us(int usec){ usec = (int)(CLOCK*usec)/ 10; while(usec) { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); usec--; } } /*************************** * msec単位ディレイ関数 ***************************/ void delay_ms(int msec){ int i; for(i=0; i< msec; i++) delay_us(1000); } //------------------------------------------------------------------------------------------------ //-------------------------------------------------------------------------------------------------- //****************************************************************** // 受信側 PIC //****************************************************************** #include <16F873.h> #use delay(clock=10000000) #FUSES HS,NOWDT,,PUT,BROWNOUT,NOPROTECT,NOLVP #use RS232(BAUD=19200,XMIT=PIN_C6,RCV=PIN_C7) // TX=RC6,RX=RC7 #define STX 0x02 // STX #use fast_io(B) //////// Port define and link LCD library #define mode 0 // 液晶 #define input_x input_B #define output_x output_B #define set_tris_x set_tris_B #define rs PIN_B1 //chip select #define stb PIN_B0 //strobe #include <1lcd_lib.c> int n = 0,i=0; char RX1[17],RX2[17]; char RX1_LCD[17],RX2_LCD[17]; int data1; int LineMode = 1; void LCD() { data1 = getc(); switch(data1) { case '\r': LineMode = 1; // 1行目のモード n = 0; // 文字送信順番リセット break; case '\n': // lcd_cmd(0xC0); case 0x0a: LF('\n')なら 2行目の先頭へ LineMode = 2; n = 0; // 文字送信順番リセット break; case STX: // 表示開始命令 for(i = 0; i < 16; i++) { RX1_LCD[i] = RX1[i]; //1行目のデータ RX1_LCD[16] = '\0'; RX2_LCD[i] = RX2[i]; //2行目のデータ RX2_LCD[16] = '\0'; } lcd_clear(); //液晶クリア printf(lcd_data,RX1_LCD); //1行目のデータを一括液晶表示 lcd_cmd(0xC0); //2行目の先頭へ printf(lcd_data,RX2_LCD); //2行目データを一括液晶表示 break; default: switch(LineMode) { case 1: //1行目のデータ RX1[n] = data1; break;//1行目データをメモリに記憶 case 2: //2行目のデータ RX2[n] = data1; break;//2行目データをメモリに記憶 default: break; } n++; break; } } main(){ lcd_init(); lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); printf(lcd_data,"First Line"); lcd_cmd(0xC0);//2行目の先頭へ printf(lcd_data,"Second Line"); // delay_ms(500); while(1) { if(kbhit()) LCD(); //RS232Cのデータ(1バイト)が受信完了しているなら LCD()実行 } return 0; } //------------------------------------ //その他 FAT関連のインクルーファイルは下記にあります。 // ・「C言語ではじめるPIC24F活用ガイドブック」後閑哲也著 (技術評論社) // ・後閑哲也さんのホームページ: 電子工作実験室 PIC24F製作例
<動作結果>
1. 液晶画面
液晶画面 | 備考 | |
mp3ファイル再生中 | エデンの東(ファイル名:EDENEAST.mp3)を演奏中の液晶画面 | |
wavファイル録音中 | マイクからの音声をWAVファイル(ファイル名:VOICE.wav)に録音中の液晶画面 |
|
wavファイル再生中 | 録音したWAVファイル(ファイル名:VOICE.WAV)を再生中の画面 |
2. 録音したwavファイル(例)
試作品で録音した wavファイル(VOICE.wav)です。 PCで再生してみてください。
3.wavファイルのバイナリーデータ
上記2.のVOICE.wavファイルの内部をバイナリーエディタで表示したものを以下に示します。
<ファイルヘッダー情報>
・ファイルサイズ ……596,024バイト ( = 0x00091838バイト) (注)
・圧縮のフォーマットID …… リニアPCM
・チャンネル数 …… モノラル
・サンプリングレート……22050 Hz
・データ転送速度 ……44100 バイト/sec
・Block align …… 2 バイト/サンプル
・量子化ビット数……16ビット
・データサイズ……595,968バイト ( = 0x00091800バイト)
(注)エクスプローラでみるとファイルサイズは582KBです。これはエクスプローラでの1KBは、1KB = 1000バイトではなく 1KB = 1024バイトに
よる誤差(?)からくるものです。
596024 ÷ 1024 = 582.05 [KB]
<バイナリーエディタによるVOICE.WAV内部>
(2) PIC32MX795F512L 編
PIC32MX版も製作しましたので紹介します。 仕様は 上記のPIC24FJ64GA002と同じです。
PIC32MX795F512Lを使用した、WAVファイル形式録音機能付きMP3プレーヤーを紹介します。MP3のデコーダーICとしてはVS1011Eを
使用しています。 VS1011Eのライブラリ関数(VS1011.h、VS1011.c)は後閑哲也さんが設計されたものです。後閑さんには本プレーヤー製作に
あたり貴重なアドバイスを多々いただきました。
★ mp3デコーダーIC VS1011Eは QFPがキバンにハンダ付けされ、端子が2.54インチのピンヘッダーコネクタに変換されたもの(700円/個)が
秋月電子で販売されています。私はこれをつかって試作品を製作しました。
<試作品の仕様>
・再生モードと録音モードを有すること。再生、録音のモード切替はモメンタリースイッチでおこなうこと
・mp3ファイルについては再生のみとし、エンコード機能はつけない
・mp3、wav形式でSDカードに収録されている音楽・音声データを再生できること
・mp3ファイルのデコーダICとして、VS1011Eを使用すること
・再生はSDカード内にある音楽・音声データを順番におこなう。但し、スキップボタンをもうけ再生データをスキップできるようにすること
・録音は、マイクレベルの音声信号を増幅しPICでAD変換して、データはSDカードにWAV形式のファイルとしてファイルすること
・録音するWAVファイルの諸元は下記とする
@圧縮のフォーマットID …… リニアPCM
Aチャンネル数 …… モノラル
Bサンプリングレート……22050 Hz
Cデータ転送速度 ……44100 バイト/sec
DBlock align …… 2 バイト/サンプル
E量子化ビット数……16ビット
・録音するファイル名はVOICE.wavとする。SDカード内のルートにこのファイル名のファイルが存在しない場合はファイルをつくること。 また、
すでにVOICE.wavが存在する場合は上書きするものとする。
・キャラクタ液晶により、録音/再生時のファイル名を表示する。
<試作品の回路図> (→ 回路図のPDFファイル)
<試作品外観>下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています
<プログラム例> //MPLAB X //main.c //------------------------------------------------------------------------------------------ //32MX795 MEB SD Play with wave Recorder #include <p32xxxx.h> #include <plib.h> // PIC32 peripheral library #include "1lcd_lib_C32.h" #include "FSIO.h" #include "VS1011.h" #define STX 0x02 //STX #define ETX 0x03 //ETX // configuration CPU=80MHz Peri=80MHz,HS+PLL,Divider=1/2,PLL=x20,WDT=Off #pragma config FNOSC=PRIPLL, POSCMOD=HS, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_1 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 //WAVEファイルヘッダ構造体定義 struct myWaveHeader //全ヘッダサイズ: 44バイト { char id_RIFF[4]; //Chunk ID RIFFヘッダ // 4バイト unsigned int size_file; //ファイルサイズ(総ファイルサイズ - 8)バイト //4バイト char id_WAVE[4]; //Chunk ID WAVE //4バイト char id_fmt[4]; //Chunk ID fmt //4バイト unsigned int size_fmt; //フォーマット関連定義データのサイズ //4バイト unsigned short int code_wavefmt; //WAVEファイルの圧縮フォーマットコード 但し、リニアPCMは圧縮なし//2バイト unsigned short int channel; //チャンネル数 //2バイト unsigned int rate_sample; //サンプリングレート //4バイト unsigned int rate_tranfer; //転送速度[byte/sec] //4バイト unsigned short int align_block; //サンプルあたりのバイト数[byte/サンプル] //2バイト unsigned short int bit_sample; //量子化ビット数[bit] //2バイト char id_data[4]; //Chunk ID data //4バイト unsigned int size_data; //サンプリングデータのサイズ[byte] //4バイト } ; struct myWaveHeader mywaveheader = // WAVEファイルヘッダ構造体の初期化 //44バイト { "RIFF", //Chunk ID RIFF // 4バイト 0x0006C28C, //(仮)ファイルサイズ: 443020バイト //特に値に意味なし "WAVE", //Chunk ID WAVE //4バイト "fmt ", //char id_fmt[4]; //Chunk ID fmt //4バイト 16, //16バイト at リニアPCM フォーマット関連定義データのサイズ //4バイト 0x0001, //WAVEファイルの圧縮フォーマットコード: リニアPCM //2バイト 1, //チャンネル数: モノラル //2バイト 22050, //サンプリングレート: 22.05[KHz] //4バイト 44100, //転送速度: 44100[byte/sec] //4バイト //サンプリングレート: 22.05[Hz] 2, //サンプルあたりのバイト数: 2[byte]/サンプル //2バイト 16, //量子化ビット数: 16[bit] //2バイト "data", //Chunk ID data //4バイト 0x0006C267 ////(仮)サンプリングデータのサイズ: 442983バイト //特に値に意味なし }; struct myWaveHeader* ptrWH; //構造体のポインタ char Buf[17]; //文字列のバッファー用レジスタ unsigned int Buf_Input[3]; //SDカード書き込み値 unsigned int Buf_SD[3]; //SDカード読込み値 // FATファイル用構造体のポインタ変数 FSFILE* pfile; //SDカードのファイルポインタ //FSFILE *fptr; size_t result; BYTE Buffer[256]; SearchRec Record; SearchRec *rptr = &Record; int i; // MP3用変数 BYTE Volume, ChgFlag, BASS; int Mode = 0; //録音/再生モード 0:再生 1:録音 unsigned int adr_SD; unsigned int count_block = 0; //SD送信ブロック(512バイト)数 unsigned int size_dataBlock = 512; int count_buf1 = 0; //バッファ1データ数 int count_buf2 = 0; //バッファ2データ数 int flag_buf1 = 0; //音声データバッファ1の状態 int flag_buf2 = 0; //音声データバッファ2の状態 // 0:音声データ受信可能状態 1:SDへ音声データ送信可能状態 int mode_tranceive = 0; //送受信モード //0: バッファ1=音声タ受信、バッファ2=SD送信 //1: バッファ1=SD送信モード、バッファ2=音声受信 short int data1_sound[512]; //音声データバッファ1 short int data2_sound[512]; //音声データバッファ2 char* str_filename; int Stop_SDwriting = 0;// 1: SDカードへの書込み停止 0: 書込み許可 int Next = 0; void delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do //実測: at Clock=80000000 { //delay_us(1000)→1003μsec、 delay_us(100)→102μsec、delay_us(10)→11μsec、delay_us(1)→1.6μsec asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) delay_us(1000); } void LcdCheck(void) { INTDisableInterrupts(); //全割り込み禁止 // SPI処理中は割り込み禁止 lcd_clear(); // 全消去 lcd_cmd(0x80); //1目の先頭へ sprintf(Buf,"M=%d block=%d",Mode,count_block); // lcd_str(Buf); //液晶表示 lcd_cmd(0xC0); //2行目の先頭へ sprintf(Buf,"result=%d",result); lcd_str(Buf); // 開始メッセージ1行目表示 while(1); } void wav_end(void) //録音ファイル完成処理 { unsigned int result; int count_N; mywaveheader.size_data = count_block * 1024 ; //[バイト] mywaveheader.size_file = count_block * 1024 + sizeof mywaveheader - 8; //[バイト] delay_ms(100); result = FSfseek(pfile,0,SEEK_SET); //ファイルの先頭にファイルポインタの位置を移動 delay_ms(100); result = FSfwrite((const void*)ptrWH,sizeof(struct myWaveHeader),1,pfile); //ファイルにヘッダー情報書き込み delay_ms(100); result = FSfclose(pfile); // ファイルを閉じる } void SD_write() { if(mode_tranceive == 0) //バッファ2=SD送信、バッファ1=音声受信モード { if(flag_buf2 == 1) //バッファ2がSDへ送信可能状態の場合・バッファ1は音声受信可能状態 { // FSfwrite((const void*)data2_sound,sizeof(short int),size_dataBlock,pfile);//SDカードにデータ書き込み FSfwrite((const void*)data1_sound,sizeof(short int),size_dataBlock,pfile);//SDカードにデータ書き込み count_block++; flag_buf2 = 0; //→ バッファ2送信完了、受信可能状態 } } else //バッファ1=SDへ送信可、バッファ2=音声受信モード { if(flag_buf1 == 1) //バッファ1がSDへ送信可能状態の場合・バッファ2は音声受信可能状態 { // FSfwrite((const void*)data1_sound,sizeof(short int),size_dataBlock,pfile);//SDカードにデータ書き込み FSfwrite((const void*)data2_sound,sizeof(short int),size_dataBlock,pfile);//SDカードにデータ書き込み count_block++; flag_buf1 = 0; //→ バッファ1送信完了、受信可能状態 } } if(Stop_SDwriting == 1) // { delay_ms(200); wav_end(); //録音wavファイル終了処理 Mode = 0; //音楽再生モードへ delay_ms(1000); pfile = FSfopen("VOICE.WAV", "r"); // ファイルのオープン } } void __ISR(4,ipl5)T1Hander(void) //タイマ1割込 45.3μsec毎(22.05 KHz) { unsigned int temp1; int temp2; mT1ClearIntFlag(); //フラグクリア AD1CON1bits.SAMP =1; //サンプリング開始 while(!AD1CON1bits.DONE); //AD変換終了フラグがたつ(1になるまで)待つ temp1 = ADC1BUF0; //ADC1のAN1のバッファーからAD変換結果を読込む temp2 = temp1*64 - 32768; //32768 = 64*1024 / 2; //無音基準レベル:32768( = unsigned int / 2) if(temp2 >= 32767) temp2 = 32767; //音声レベルクリップ if(temp2 <= -32768)temp2 = -32768; //送信優先: 未送信データがバッファに残っている場合は入力する音声データは無視する if(mode_tranceive == 0) //バッファ1=音声受信、バッファ2=SD送信 { if(flag_buf1 == 0) //バッファ1が受信可能状態なら { LATDbits.LATD2 = 0; delay_us(2); data1_sound[count_buf1] = (short int)temp2; //受信データをバッファ構造体1のdata_sound[ ]に保存 count_buf1++; if(count_buf1 >= size_dataBlock) { count_buf1 = 0; flag_buf1 = 1; //→ バッファ1: 音声データフル・SD転送待ち mode_tranceive = 1; //バッファ1=SD送信モード、バッファ2=音声受信 } LATDbits.LATD2 = 1; } //バッファ1にまだ未送信音声データが残っていた場合は、音声データは受信しない } else //バッファ2=音声受信、バッファ1=SD送信 { if(flag_buf2 == 0) //バッファ2が受信可能状態なら { LATDbits.LATD3 = 0; delay_us(2); data2_sound[count_buf2] = (short int)temp2; //受信データをバッファ構造体2のdata_sound[ ]に保存 count_buf2++; if(count_buf2 >= size_dataBlock) { count_buf2 = 0; flag_buf2 = 1; //→ バッファ2:音声データフル・SD転送待ち mode_tranceive = 0; //バッファ1=音声タ受信、バッファ2=SD送信 } LATDbits.LATD3 = 1; } } //バッファ2にまだ未送信音声データが残っていた場合は、音声データは受信しない } void __ISR(26,ipl2)ChangeInt(void) //変化割り込み //スイッチ検出 { if(!PORTBbits.RB0) //再生/録音ボタンがクリックされた場合 { if(Mode == 0) //再生モードの場合 { Mode = 1; //録音モードへ Stop_SDwriting = 0; //SDカードへの書き込み許可 MP3_XDCS_IO = 1; //VS1011E 音データ信号ラインOFF MP3_XCS_IO = 1; //VS1011E チップセレクト解除 FSfclose(pfile); // 現在のファイルを強制クローズ PlayEnd(); // 再生終了処理 delay_ms(200); pfile = FSfopen("VOICE.wav","w"); //ファイル上書き込みモードでオープン 但しファイルがなければ新規ファイル作成 lcd_clear(); // 全消去 lcd_cmd(0x80); //1行目の先頭へ sprintf(Buf,"VOICE.WAV"); //ファイル名 //空白必須 lcd_str(Buf); // 開始メッセージ1行目表示 lcd_cmd(0xC0); //2行目の先頭へ sprintf(Buf,"On recording"); //タッチY座標表示 lcd_str(Buf); // 開始メッセージ2行目表示 ptrWH = &mywaveheader; //構造体にmywaveheaderの先頭アドレス設定 FSfseek(pfile,0,SEEK_SET); //ファイルの先頭にファイルポインタの位置を移動 delay_ms(50); FSfwrite((const void*)ptrWH,sizeof(struct myWaveHeader),1,pfile); //ファイルにヘッダー情報書き込み delay_ms(50); adr_SD = 0x2C; //ファイルの先頭から0x2C(44)バイト(音声データ書き込み開始オフセット)のところにに FSfseek(pfile,adr_SD,SEEK_SET);//ファイルポインタの位置を移動 count_block = 0; //SDカードに512バイト単位で書き込んだ回数をリセット delay_ms(300); ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_5); //タイマ1割込ON、割り込みレベル5 EnableIntT1; //割込み許可 } if((Mode == 1) && (count_block >= 10)) //録音モード かつ 10ブロック以上書き込んでいるななら(チャタリング防止) { ConfigIntTimer1(T1_INT_OFF | T1_INT_PRIOR_5); //タイマ1割込ON、割り込みレベル5 // ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_OFF); //タイマ1: 割り込み優先レベル5 // IPC0bits.T1IP = 5; DisableIntT1; //タイマ1: 割り込み禁止 //IEC0bits.T1IE = 0; Stop_SDwriting = 1; //SDカード書込み終了 //1ブロック書込み後終了処理開始 //★ここですぐ終了処理を行わないこと!! } } if(!PORTBbits.RB1) //スキップボタンがクリックされた場合 { Next = 1; //再生中のファイルのセクタ読み込み終了後、次の曲を再生 } mCNClearIntFlag(); // 変化割り込みフラグクリア //IFS1bits.CNIF = 0; } void play() // 音楽データの出力 { int i; ConfigIntTimer1(T1_INT_OFF | T1_INT_PRIOR_5); //タイマ1割込ON、割り込みレベル5 //ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_OFF); //タイマ1割込み禁止 DisableIntT1; if(pfile != 0) // 正常にオープンできたか? { do{ // ファイルのEOFまで音声データ連続出力 INTDisableInterrupts(); //全割り込み禁止 MP3_XDCS_IO = 0; //#define MP3_XDCS_IO LATBbits.LATB15=0 → DREQ=0 result = FSfread(Buffer, 1, 256, pfile); //SDカードのデータを256バイト単位で読み出し for(i= 0; i<result; i++) // 読み出したバイト数だけ繰り返し { SendData(Buffer[i]); // 音楽データ送信 } INTEnableInterrupts(); //全割り込み許可 if(Mode == 1)return; //録音モードなら 再生は終了 if(Next == 1)result = 0; } while(result != 0); // ファイルのEOFまで継続 Next = 0; MP3_XDCS_IO = 1; // 再生完了処理 FSfclose(pfile); // ファイルのクローズ PlayEnd(); // 再生終了処理 result = FindNext(rptr); // 連続再生のため次のファイルへ if((result != 0) || (Record.attributes != ATTR_ARCHIVE)) FindFirst("*.*", ATTR_ARCHIVE, rptr); // ファイルの終わりなら再度最初から繰り返し pfile = FSfopen(Record.filename, "r"); str_filename = Record.filename; lcd_clear(); // 全消去 lcd_cmd(0x80); //1行目の先頭へ sprintf(Buf,"%s ",str_filename); //ファイル名 //空白必須 lcd_str(Buf); // 開始メッセージ1行目表示 // 開始メッセージ2行目表示 INTEnableInterrupts(); //全割り込み許可 } } int main(void) { SYSTEMConfigPerformance(80000000); // システム最適化 INTEnableSystemMultiVectoredInt(); //マルチベクタ方式割り込み許可 mJTAGPortEnable(DEBUG_JTAGPORT_OFF); //JTAG無効化//DDPCONbits.JTAGEN = 0; //I/OポートとしてRA0、RA1、RA4、RA5をつかう場合必須 //ADコンバータ初期設定 //音声入力 AD1PCFG = 0xFEFF; //b8=0以外は1 //Bポート:b8以外はデジタルピン TRISBbits.TRISB8 = 1; //RB8/AN8を入力ピンに設定 //AD1CON1レジスタの設定 AD1CON1bits.ON = 1; //A/Dコンバータモジュール有効 AD1CON1bits.SIDL = 0; //アイドルモード中もモジュール動作継続 AD1CON1bits.FORM2 = 0; //AD1CON1bits.FORM2-AD1CON1bits.FORM0のセットで出力データ形式指定 → 000:16ビット符号なし整数形式 AD1CON1bits.FORM1 = 0; //011:符号付固定16ビット小数 010:固定小数16ビット 001:符号付き整数16ビット 000:16ビット符号なし整数 AD1CON1bits.FORM0 = 0; //111:符号付32ビット固定小数 110:32ビット固定小数 101:符号付32ビット整数 100=32ビット符号なし整数 AD1CON1bits.SSRC2 = 1; //AD1CON1bits.SSRC2-AD1CON1bits.SSRC0 のセットでトリガーソースを指定 AD1CON1bits.SSRC1 = 1; //111: 内蔵カウンタでサンプリングを終了させ変換を開始する AD1CON1bits.SSRC0 = 1; //(参考)000: SAMPビットでサンプリングを終了し変換を開始する AD1CON1bits.CLRASAM = 0;//AD変換割り込み時の変換停止 0:次の変換値でオーバーライト AD1CON1bits.ASAM = 0; //SAMPビットのセットでサンプリングを開始する。(参考)1: 自動開始(前の変換終了後すぐサンプリングを開始する) AD1CON1bits.SAMP = 0; //サンプリング停止 //AD1CON2レジスタの設定 AD1CON2bits.VCFG2 = 0; //リファレンス選択//AD1CON2bits.VCFG2 - AD1CON2bits.VCFG0(VCFG<2:0>)の3ビットでセット AD1CON2bits.VCFG1 = 0; //000:リファレンス電圧 → Vdd -Vss AD1CON2bits.VCFG0 = 0; //(参考)001:リファレンス電圧 → 外部入力 - Vss 他 AD1CON2bits.OFFCAL = 0; //較正モード設定 0:サンプルホールドアンプSHAの入力はAD1CHSレジスタとAD1CSSLレジスタで制御される AD1CON2bits.CSCNA = 1; //マルチプレクサMUXAでのスキャン: する AD1CON2bits.SMPI3 = 0; //割り込みタイミング AD1CON2bits.SMPI3 - AD1CON2bits.SMPI0(SMPI<3:0>)の4ビットでセット AD1CON2bits.SMPI2 = 0; //0000: AD変換完了毎の割り込み発生(割り込み有効の場合) AD1CON2bits.SMPI1 = 0; //(参考)0011: 4サンプルのAD変換終了後 割り込み発生(割り込み有効の場合) AD1CON2bits.SMPI0 = 0; // AD1CON2bits.BUFM = 0; //バッファーを1個の16ワードバッファとする。 (参考)1: 2組の8ワードバッファーとする AD1CON2bits.ALTS = 0; //常にMUXAを入力マルチプレクサにする (参考)1: MUXA,MUXBを交互につかう //AD1CON3レジスタの設定 AD1CON3bits.ADRC = 0; //AD変換クロック源選択//0: PBCLK(Peripheral Bus Clock) (参考)1: A/D内臓RCクロック AD1CON3bits.SAMC4 = 1; //AD1CON3bits.SAMC4 - AD1CON3bits.SAMC0(SAMC<4:0>)の5ビットでセット AD1CON3bits.SAMC3 = 1; //アクイジションタイム(Tad(クロック周期)×N)設定(ホールドキャパシタ充電所要時間) AD1CON3bits.SAMC2 = 1; //1111: 31Tad AD1CON3bits.SAMC1 = 1; //(参考)0001: 1Tad 0010: 2Tad 0011: 3Tad ・・・・ AD1CON3bits.SAMC0 = 1; // AD1CON3bits.ADCS7 = 0; //AD変換時間の設定/AD1CON3bits.ADCS7 - AD1CON3bits.ADCS0(ADCS<7:0>)の8ビットでセット //AD変換完了フラグAD1CON1bits.DONEにより、AD変換完了を検知する場合は設定不要 AD1CON3bits.ADCS6 = 0; //AD変換完了までののクロック数選択ビット AD1CON3bits.ADCS5 = 0; //0000 0101: 1Tad = 6Tpb (Tpb: PBCLKの周期) AD1CON3bits.ADCS4 = 0; //(参考) 0000 0000: 1Tad = 2Tpb AD1CON3bits.ADCS3 = 0; // 0000 0001: 1Tad = 3Tpb AD1CON3bits.ADCS2 = 1; // 0000 0010: 1Tad = 4Tpb AD1CON3bits.ADCS1 = 0; // ・・・・ AD1CON3bits.ADCS0 = 1; // 1111 1111: 1Tad = 512Tpb //AD1CHSレジスタの設定 //SHAの+端子とー端子への接続(ポート)設定 AD1CHSbits.CH0NB = 0; //マルチプレクサMUXB用負側入力選択ビット: VR- (参考)1: AN1 AD1CHSbits.CH0SB3 = 0; //AD1CHSbits.CH0SB3 - AD1CHSBbits.CH0SB0(<CH0SB<3:0>)の4ビットでセット AD1CHSbits.CH0SB2 = 0; //マルチプレクサMUXBの正側入力選択 AD1CHSbits.CH0SB1 = 0; //0000: AN0 AD1CHSbits.CH0SB0 = 0; //(参考)0001: AN1 0011 AN2 .... 1111: AN15 AD1CHSbits.CH0NA = 0; //マルチプレクサMUXA用負側入力選択ビット: VR- (参考)1: AN1 AD1CHSbits.CH0SA3 = 0; //AD1CHSbits.CH0SA3 - AD1CHSbits.CH0SA0(<CH0SA<3:0>)の4ビットでセット AD1CHSbits.CH0SA2 = 0; //マルチプレクサMUXAの正側入力選択 AD1CHSbits.CH0SA1 = 0; //0000: AN0 AD1CHSbits.CH0SA0 = 0; //(参考)0001: AN1 0011 AN2 .... 1111: AN15 //AD1PCFGレジスタの設定 // ポートのアナログorデジタル設定 //★デバイスリセットでは全ビット0となるためデフォルトではアナログ入力となるのでデジタルで使う多重ピンは、コンフィグレーションでデジタル設定が必要!! AD1PCFGbits.PCFG15 = 1;//RB15/AN15アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG14 = 1;//RB14/AN14アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG13 = 1;//RB13/AN13アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG12 = 1;//RB12/AN12アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG11 = 1;//RB11/AN11アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG10 = 1;//RB10/AN10アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG9 = 1;//RB9/AN9アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG8 = 0;//RB8/AN8アナログ入力orデジタル入力選択: アナログ //★AN8から音声を入力する AD1PCFGbits.PCFG7 = 1;//RB7/AN7アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG6 = 1;//RB6/AN6アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG5 = 1;//RB5/AN5アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG4 = 1;//RB4/AN4アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG3 = 1;//RB3/AN3アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG2 = 1;//RB2/AN2アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG1 = 1;//RB1/AN1アナログ入力orデジタル入力選択: デジタル AD1PCFGbits.PCFG0 = 1;//RB0/AN0アナログ入力orデジタル入力選択: デジタル //AD1CSSLレジスタの設定 //読み込むチャンネル(入力端子)をセットする AD1CSSLbits.CSSL15 = 0; //AN15をMUXAでスキャンしない AD1CSSLbits.CSSL14 = 0; //AN15をMUXAでスキャンしない AD1CSSLbits.CSSL13 = 0; //AN13をMUXAでスキャンしない AD1CSSLbits.CSSL12 = 0; //AN12をMUXAでスキャンしない AD1CSSLbits.CSSL11 = 0; //AN11をMUXAでスキャンしない AD1CSSLbits.CSSL10 = 0; //AN10をMUXAでスキャンしない AD1CSSLbits.CSSL9 = 0; //AN9をMUXAでスキャンしない AD1CSSLbits.CSSL8 = 1; //AN8をMUXAでスキャンする //★使用するAN8のチャンネルだけ読み込む AD1CSSLbits.CSSL7 = 0; //AN7をMUXAでスキャンしない AD1CSSLbits.CSSL6 = 0; //AN6をMUXAでスキャンしない AD1CSSLbits.CSSL5 = 0; //AN5をMUXAでスキャンしない AD1CSSLbits.CSSL4 = 0; //AN4をMUXAでスキャンしない AD1CSSLbits.CSSL3 = 0; //AN3をMUXAでスキャンしない AD1CSSLbits.CSSL2 = 0; //AN2をMUXAでスキャンしない AD1CSSLbits.CSSL1 = 0; //AN1をMUXAでスキャンしない AD1CSSLbits.CSSL0 = 0; //AN0をMUXAでスキャンしない //キャラクタ液晶ポート入出力設定 //関数初期化 TRISBbits.TRISB15 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB14 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB13 = 0; //キャラクタ液晶ポート設定 TRISBbits.TRISB12 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA9 = 0; //キャラクタ液晶ポート設定 TRISAbits.TRISA10 = 0; //キャラクタ液晶ポート設定 /// インターバルタイマ1 周期 45.3μsec (音データサンプリング周期) OpenTimer1( T1_ON | // タイマ1 イネーブル //T1_OFF → タイマ1 ディセーブル T1_SOURCE_INT | //クロックソース:インターナル //T1_SOURCE_EXT → 外部発振器 T1_PS_1_1, //プリスケール 1/256 //1/1、1/2、1/4、1/8、1/16、1/32、1/64、1/256 3624 //PRx値: T0[μsec] = 1000x1000/80000000x3624 = 1/80x3624 = 45.3μsec ); //状態変化モジュール(スイッチ検出)初期設定 mCNOpen( CN_ON, //状態変化モジュール ON CN2_ENABLE | //CN2 Enable //RB0 CN3_ENABLE , //CN3 Enable //RB1 // CN5_ENABLE, //CN5 Enable //RB3 CN2_PULLUP_ENABLE | //CN2 プルアップ抵抗設定 CN3_PULLUP_ENABLE //CN3 プルアップ抵抗設定 // CN5_PULLUP_ENABLE //CN5 プルアップ抵抗設定 ); ConfigIntCN(CHANGE_INT_ON | CHANGE_INT_PRI_2); //状態変化割り込みON、優先度2 //SDカード関係(SPI4等)ポート設定 --> HardwareProfile.h //VS1011e関係(含SPI3)ポート設定 --> VS1011.h,VS1011.c //INT035TFT関係ポート設定 --> HardwareProfile.h // VS1011eの初期化 VS1011_Init(); Volume = 0x08; // 音量の初期設定 SetVolume(Volume, Volume); BASS = 0; // バスブーストの初期設定 SetBassBoost(BASS,15); // VS1011のデバッグ時テスト用のコマンド // VS1011_SineTest(); // 正弦波出力テスト // カードの実装確認とディレクトリ読み込み (永久待ち) while(!FSInit()); result = FindFirst("*.*", ATTR_ARCHIVE, rptr); //最初のファイルのサーチ(ルートだけにMP3ファイルがあることが前提) if(result == 0) { pfile = FSfopen(Record.filename, "r"); // ファイルのオープン str_filename = Record.filename; } Mode = 0; lcd_init(); // LCD初期化 lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF lcd_clear(); // 全消去 sprintf(Buf,"Record 6 Player"); lcd_str(Buf); //液晶表示 delay_ms(1000); TRISDbits.TRISD2 = 0; TRISDbits.TRISD3 = 0; TRISGbits.TRISG15 = 0; LATGbits.LATG15 = 0; LATDbits.LATD3 = 0; LATDbits.LATD2 = 0; LATDbits.LATD2 = 1; LATDbits.LATD3 = 1; LATGbits.LATG15 = 1; while(1) { if(Mode == 0)play(); //再生モード else SD_write(); //録音モード } return 0; } //---------------------------------------------------------------------------------------------------------- //HardwareProfile.h //Microchip Memory Disk Drive File System #ifndef _HARDWAREPROFILE_H_ #define _HARDWAREPROFILE_H_ //クロック周波数設定 システムクロック:80MHZ #define GetSystemClock() (80000000ul) //システムクロック #define GetPeripheralClock() (GetSystemClock()/2) //ペリフェラルクロック #define GetInstructionClock() (GetSystemClock()) //インストラクションクロック // Clock values // #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer // #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer // #define TIMER_PERIOD 37500 // Definition for use with a tick timer // Description: Macro used to enable the SD-SPI physical layer (SD-SPI.c and .h) #define USE_SD_INTERFACE_WITH_SPI //SD カード選択・検出 //CS:チップセレクト // Description: SD-SPI Chip Select Output bit #define SD_CS LATDbits.LATD14 #define SD_CS_TRIS TRISDbits.TRISD14 //CD:カードディテクト // Description: SD-SPI Card Detect Input bit #define SD_CD PORTFbits.RF12 #define SD_CD_TRIS TRISFbits.TRISF12 //WE:ライトイネーブル Description: SD-SPI Write Protect Check Input bit #define SD_WE PORTAbits.RA1 #define SD_WE_TRIS TRISAbits.TRISA1 //SPIコンフィギュレーション //SPI Configuration #define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) #define SPI_START_CFG_2 (SPI_ENABLE) #define SPI_FREQUENCY (4000000) //SPI周波数 //Define the SPI frequency // #define SPI_FREQUENCY (20000000) //SPI周波数 //Define the SPI frequency //チャンネル4: #define SPICON1 SPI4CON //制御レジスタ #define SPISTAT SPI4STAT //SPIステータスレジスタ status register #define SPIBUF SPI4BUF //SPIバッファレジスタ #define SPISTAT_RBF SPI4STATbits.SPIRBF //受信バッファ満杯ビット// The receive buffer full bit in the SPI status register #define SPICON1bits SPI4CONbits //ビット単位の定義(制御レジスタ)The bitwise define for the SPI control register (i.e. _____bits) #define SPISTATbits SPI4STATbits //ビット単位の定義(ステータスレジスタ) //The bitwise define for the SPI status register (i.e. _____bits) #define SPIENABLE SPI4CONbits.ON //SPIモジュール イネーブルビット //The enable bit for the SPI module #define SPIBRG SPI4BRG //ボーレートジェネレータ//The definition for the SPI baud rate generator register (PIC32) //SCK,SDI,SDOピンアサイン //Tris pins for SCK/SDI/SDO lines #define SPICLOCK TRISFbits.TRISF12 //TRISGbits.TRISG6 //SCK #define SPIIN TRISFbits.TRISF4 //PICのSDI4 // TRISGbits.TRISG7 //PICのSDI2 #define SPIOUT TRISFbits.TRISF5 //PICのSDO4 // TRISGbits.TRISG8 //SDO //SPIライブラリ関数 //library functions // #define putcSPI putcSPI4 //putcSPI2 // #define getcSPI getcSPI4 //getcSPI2 // #define OpenSPI(config1, config2) OpenSPI4(config1, config2) //OpenSPI2(config1, config2) // #include <uart2.h> #endif //------------------------------------------------------------------------------------------------------------------------------------- /********************************************************************* * VS1011E用ヘッダファイル * ********************************************************************/ //このファイルは 後閑哲也さんがPIC24FJ64GA002用に設計されたファイルを //PIC32MX795F512L用に変更したものです。 #include "GenericTypeDefs.h" //Delay関数用クロック周波数定義 //#define CLOCK 16 // MHz // ポートの定義 #define MP3_DREQ_TRIS (TRISAbits.TRISA15) //(TRISBbits.TRISB14) // Data Request #define MP3_DREQ_IO (PORTAbits.RA15) //(PORTBbits.RB14) #define MP3_XRESET_TRIS (TRISDbits.TRISD11) //(TRISAbits.TRISA0) // Reset, active low #define MP3_XRESET_IO (LATDbits.LATD11) //(LATAbits.LATA0) #define MP3_XDCS_TRIS (TRISAbits.TRISA5) //(TRISBbits.TRISB15) // Data Chip Select #define MP3_XDCS_IO (LATAbits.LATA5) //(LATBbits.LATB15) #define MP3_XCS_TRIS (TRISAbits.TRISA14) //(TRISBbits.TRISB13) // Control Chip Select #define MP3_XCS_IO (LATAbits.LATA14) //(LATBbits.LATB13) //SPI3を使用 // SPIはSPI2を使用 #define MP3_SCK_TRIS (TRISDbits.TRISD15) //SDK3/RD15 (TRISBbits.TRISB12) //VS1011e #define MP3_SDI_TRIS (TRISFbits.TRISF2) //SDI3/RF2 (TRISBbits.TRISB10) #define MP3_SDO_TRIS (TRISFbits.TRISF8) //SDO3/RF8 (TRISBbits.TRISB11) #define MP3_SPI_IF (IFS0bits.SPI3RXIF) //RX書込み完了フラグ //(IFS2bits.SPI2IF)/Flag Status bit 1:interrupt occured 0:interrupt not occured #define MP3_SSPBUF (SPI3BUF) // (SPI2BUF) #define MP3_SPICON1 (SPI3CON) // (SPI2CON1) //#define MP3_SPICON1bits (SPI3CONbits) //(SPI2CON1bits) //#define MP3_SPICON2 (SPI3CON) //SPI2CON2 //#define MP3_SPISTAT (SPI3STAT) //(SPI2STAT) //#define MP3_SPISTATbits (SPI3STATbits) //(SPI2STATbits) /* 関数プロトタイピング */ BYTE WriteSPI(BYTE output); void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData); void SendData(BYTE Data); //void delay_ms(int msec); void VS1011_Init(void); void VS1011_SineTest(void); void SetVolume(BYTE right, BYTE left); void SetBassBoost(BYTE bass, BYTE gfreq); void PlayEnd(void); //------------------------------------------------------------------------------------------------------------------------ // /***************************************************** * VS1011E 制御ライブラリ * ******************************************************/ //このファイルは 後閑哲也さんがPIC24FJ64GA002用に設計されたファイルを //PIC32MX795F512L用に変更したものです。 #include "VS1011.h" #include <p32xxxx.h> //#include <p24FJ64GA002.h> /************************************ * SPI Read after Write 基本関数 ************************************/ BYTE WriteSPI(BYTE output){ MP3_SPI_IF = 0; //受信完了フラグクリア // 割り込みフラグクリア MP3_SSPBUF = output; // SPI出力 while(!MP3_SPI_IF); //受信完了割込みフラグ待ち // 入力待ち return MP3_SSPBUF; // // 入力データ戻り値 } /************************************ * VS1011用コマンド出力関数 ************************************/ void Command(BYTE RegAdrs, BYTE UpData, BYTE LowData){ MP3_XDCS_IO = 1; // データモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // コマンドモード設定 WriteSPI(0x02); // 書き込み動作指定 WriteSPI(RegAdrs); // レジスタアドレス出力 WriteSPI(UpData); // 上位バイト出力 WriteSPI(LowData); // 下位バイト出力 MP3_XCS_IO = 1; // コマンドモード解除 } /************************************ * VS1011用コマンド出力関数(確認付き) ************************************/ void CmdCheck(BYTE RegAdrs, BYTE UpData, BYTE LowData){ BYTE b1,b2; do{ MP3_XDCS_IO = 1; // データモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // コマンドモード設定 WriteSPI(0x02); // 書き込み動作指定 WriteSPI(RegAdrs); // レジスタアドレス出力 WriteSPI(UpData); // 上位バイト出力 WriteSPI(LowData); // 下位バイト出力 MP3_XCS_IO = 1; // コマンドモード解除 while(!MP3_DREQ_IO); // レディー待ち MP3_XCS_IO = 0; // 読み込み確認 WriteSPI(0x03); // 読み込み動作 WriteSPI(RegAdrs); // レジスタアドレス指定 b1 = WriteSPI(0xFF); // return UpData b2 = WriteSPI(0xFF); // return LowData MP3_XCS_IO = 1; }while((b1 != UpData) || (b2 != LowData)); } /************************************ * VS1011用データ出力関数 ************************************/ void SendData(BYTE Data){ while(!MP3_DREQ_IO); // レディー待ち WriteSPI(Data); } /*********************************************** * 音量レベル設定関数 * vRight = 右チャネル用音量 * vLeft = 左チャネル用音量 * いすれも 0x00=Max 0dB 0.5dBステップで下がる ************************************************/ void SetVolume(BYTE vRight, BYTE vLeft){ Command(0x0B, vRight, vLeft); } /********************************************** * 低音ブースト設定制御関数 * bass: 低音ゲイン レンジは0dBから15dBの範囲 * gfreq: 低音ブースト周波数設定 10Hzステップ 0?15の範囲 ***********************************************/ void SetBassBoost(BYTE bass, BYTE gfreq) { BYTE temp1 = 0; /* 設定範囲の制限 */ if(bass > 15) bass = 15; if(gfreq > 15) gfreq = 15; /* 8ビットに合成 */ temp1 = gfreq; temp1 |= (bass << 4); Command(0x02, 0xFF, temp1); // BASS return; } /********************************************* * 再生終了処理関数 * *********************************************/ void PlayEnd(void){ int i; /* 再生バッファクリアのため2048バイト送信 */ MP3_XDCS_IO = 0; // XDCSオン for(i=0; i<2048; i++) SendData(0); // 0のデータ連続送信 MP3_XDCS_IO = 1; // XDCSオフ /*** ソフトウェアリセットで完了 **/ Command(0x00, 0x08, 0x24); // SM_RESET送信 while(!MP3_DREQ_IO); // コマンド完了待ち } /******************************************** * VS1011 初期化関数 * VS1011転送モード、SDIテストモード に設定 * VS1011と正常に通信できないと永久待ちとなる *********************************************/ void VS1011_Init(void){ unsigned int val; // VS1011用ポートの初期設定 MP3_XDCS_IO = 1; // DCSをHigh MP3_XCS_IO = 1; // XCSをHigh MP3_XRESET_IO = 0; // XRESETをLow MP3_XRESET_TRIS = 0; // 出力TRIS有効化 MP3_DREQ_TRIS = 1; // DREQ入力モードに MP3_XDCS_TRIS = 0; // XDCS出力///////// MP3_XCS_TRIS = 0; // XCS出力 MP3_SDI_TRIS = 1; // SDI2入力モード MP3_SDO_TRIS = 0; // SDO2出力モード MP3_SCK_TRIS = 0; // SCK2出力モード MP3_SPICON1 = 0x8120; // 8ビットモード,CKP = 0,CLK=Fosc/4 (4MHz) // 中央でサンプル(SMP=0) 立上りエッジで送信(CKE=1) // フレームモードなし SPI3BRG = 0x000F; // 約2.5Mbps MP3_SPI_IF = 0; // 割り込みフラグクリア // RESET解除、VS1011スタート delay_ms(50); // 50msec delay MP3_XRESET_IO = 1; // RESET解除 // モード設定 CmdCheck(0x00, 0x08, 0x20); // モード初期設定 新モード、SDIテストモード // クロックダブラ設定 val = 12288 / 2 + 0x8000; // 設定値を求める(データシートより) CmdCheck(0x03, (BYTE)(val /256), (BYTE)val); delay_ms(10); } /******************************************** * VS1011 正弦波テストモード設定関数 * MODEをSPIテストモードに設定しておく必要がある *********************************************/ void VS1011_SineTest(void) { /* テストモードシーケンス出力 */ while(!MP3_DREQ_IO); MP3_XDCS_IO = 0; // Start Sine Test WriteSPI(0x53); WriteSPI(0xEF); WriteSPI(0x6E); WriteSPI(0x7D); // 22.050kHz Out is 5kHz WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); WriteSPI(0x00); MP3_XDCS_IO = 1; } /* //usec単位ディレイ関数 void delay_us(int usec){ usec = (int)(CLOCK*usec)/ 10; while(usec) { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); usec--; } } //msec単位ディレイ関数 void delay_ms(int msec){ int i; for(i=0; i< msec; i++) delay_us(1000); } */ //************************************************************************* //インクルードファイル 1lcd_lib_C32.h //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************* #include <p32xxxx.h> //#include <proc/p32mx795f512l.h> //MX795はイニシャライズループを抜けられない //#include <proc/p32mx360f512l.h> //PIC32MX460F512L #define Clock 80000000 // 単位はHzで指定 // LCDポート設定 #define lcd_port_DB7 LATBbits.LATB15 //LCDのDB7(14番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB6 LATBbits.LATB14 //LCDのDB6(13番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB5 LATBbits.LATB13 //のDB5(12番ピン)に接続されるPIC側ポート番号設定 #define lcd_port_DB4 LATBbits.LATB12 //LCDのDB4(11番ピン)に接続されつPIC側ポート番号設定 #define lcd_rs LATAbits.LATA9 //LCDのrs(4番ピン)に接続されるPIC側ポート番号設定 #define lcd_stb LATAbits.LATA10 //LCDのstb(6番ピン)に接続されるPIC側ポート番号設定 void lcd_out(char code, char flag); void lcd_data(char asci); void lcd_cmd(char cmd); void lcd_clear(void); void lcd_init(void); void lcd_str(char *str); //************************************************************************** //インクルードファイル 1lcd_lib_C32.c //このファイルは後閑哲也さんが設計されたCCSコンパイラ用液晶表示ライブラリ 1lcd_lib.cをもとに、 //C32コンパイラ対応等で変更したものです。 //************************************************************************** /////////////////////////////////////////////// // 液晶表示器制御ライブラリ for C32コンパイラー // 内蔵関数は以下 // lcd_init() ----- 初期化 // lcd_cmd(cmd) ----- コマンド出力 // lcd_data(chr) ----- 1文字表示出力 // lcd_clear() ----- 全消去 // lcd_str(str*) ----- 文字列表示 ////////////////////////////////////////////// #include "1lcd_lib_C32.h" void lcd_delay_us(unsigned int usec) //1μsec遅延関数 { int count; count = (int)(Clock/20000000)*usec; do { asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); count--; }while(count != 0); } void lcd_delay_ms(unsigned int msec) //1msec遅延関数 { unsigned int i; for(i=0; i<msec; i++) lcd_delay_us(1000); } //////// データ出力サブ関数 void lcd_out(char code, char flag) { if(code & 0b10000000)lcd_port_DB7 = 1; //LCDのDB7への出力セット else lcd_port_DB7 = 0; if(code & 0b01000000)lcd_port_DB6 = 1; //LCDのDB6への出力セット else lcd_port_DB6 = 0; if(code & 0b00100000)lcd_port_DB5 = 1; //LCDのDB5への出力セット else lcd_port_DB5 = 0; if(code & 0b00010000)lcd_port_DB4 = 1; //LCDのDB4への出力セット else lcd_port_DB4 = 0; if (flag == 0) lcd_rs = 1; // 表示データの場合 else lcd_rs = 0; // コマンドデータの場合 lcd_delay_us(1); //1μsecウェイト lcd_stb = 1; // strobe(E) ON (Enable) lcd_delay_us(1); // 1μsec : strobe信号の幅 lcd_stb = 0; // reset strobe } //////// 1文字表示関数 void lcd_data(char asci) { lcd_out(asci, 0); // 上位4ビット出力 lcd_out(asci<<4, 0); // 下位4ビット出力 lcd_delay_us(50); //50μsecウェイト } /////// コマンド出力関数 void lcd_cmd(char cmd) { lcd_out(cmd, 1); // 上位4ビット出力 lcd_out(cmd<<4, 1); // 下位4ビット出力 if((cmd & 0x03) != 0) // clear Homeの場合 lcd_delay_ms(2); // 2msec待ち else lcd_delay_us(50); //50μsecウェイト } /////// 全消去関数 void lcd_clear(void) { lcd_cmd(0x01); // 初期化コマンド出力 } /////// 文字列出力関数 void lcd_str(char* str) { while(*str) //文字列終端の '\0'を検出するまで { lcd_data(*str); // 1文字表示 str++; //ポインタをインクリメント } } /////// 初期化関数 void lcd_init(void) { lcd_delay_ms(20); //20msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(5); //5msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x30, 1); // 8bit mode set lcd_delay_ms(1); //1msecウェイト lcd_out(0x20, 1); // 4bit mode set lcd_delay_ms(1); //1msecウェイト lcd_cmd(0x2E); // DL=0 4bit mode lcd_cmd(0x08); // display off C=D=B=0 lcd_cmd(0x0D); // display on C=D=1 B=0 lcd_cmd(0x06); // entry I/D=1 S=0 lcd_cmd(0x02); // cursor home }
//その他 FAT関連のインクルーファイルは下記にあります。 //マイクロチップのライブラリダウンロードページ: Microchip Libraries for Applications 私がつかったバージョンは \microchip_solutions_v2013-02-15 です。
<動作結果> ・ PIC32MX795F512Lで作成した音声です。 PCで聞いてみてください。 VOICE.WAV